xref: /openbmc/qemu/target/i386/tcg/translate.c (revision 0b30735d)
1 /*
2  *  i386 translation
3  *
4  *  Copyright (c) 2003 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 #include "qemu/osdep.h"
20 
21 #include "qemu/host-utils.h"
22 #include "cpu.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
25 #include "tcg/tcg-op.h"
26 #include "tcg/tcg-op-gvec.h"
27 #include "exec/cpu_ldst.h"
28 #include "exec/translator.h"
29 #include "fpu/softfloat.h"
30 
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
33 #include "helper-tcg.h"
34 
35 #include "exec/log.h"
36 
37 #define HELPER_H "helper.h"
38 #include "exec/helper-info.c.inc"
39 #undef  HELPER_H
40 
41 
42 #define PREFIX_REPZ   0x01
43 #define PREFIX_REPNZ  0x02
44 #define PREFIX_LOCK   0x04
45 #define PREFIX_DATA   0x08
46 #define PREFIX_ADR    0x10
47 #define PREFIX_VEX    0x20
48 #define PREFIX_REX    0x40
49 
50 #ifdef TARGET_X86_64
51 # define ctztl  ctz64
52 # define clztl  clz64
53 #else
54 # define ctztl  ctz32
55 # define clztl  clz32
56 #endif
57 
58 /* For a switch indexed by MODRM, match all memory operands for a given OP.  */
59 #define CASE_MODRM_MEM_OP(OP) \
60     case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
61     case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
62     case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
63 
64 #define CASE_MODRM_OP(OP) \
65     case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
66     case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
67     case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
68     case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
69 
70 //#define MACRO_TEST   1
71 
72 /* global register indexes */
73 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2;
74 static TCGv cpu_eip;
75 static TCGv_i32 cpu_cc_op;
76 static TCGv cpu_regs[CPU_NB_REGS];
77 static TCGv cpu_seg_base[6];
78 static TCGv_i64 cpu_bndl[4];
79 static TCGv_i64 cpu_bndu[4];
80 
81 typedef struct DisasContext {
82     DisasContextBase base;
83 
84     target_ulong pc;       /* pc = eip + cs_base */
85     target_ulong cs_base;  /* base of CS segment */
86     target_ulong pc_save;
87 
88     MemOp aflag;
89     MemOp dflag;
90 
91     int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
92     uint8_t prefix;
93 
94     bool has_modrm;
95     uint8_t modrm;
96 
97 #ifndef CONFIG_USER_ONLY
98     uint8_t cpl;   /* code priv level */
99     uint8_t iopl;  /* i/o priv level */
100 #endif
101     uint8_t vex_l;  /* vex vector length */
102     uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
103     uint8_t popl_esp_hack; /* for correct popl with esp base handling */
104     uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
105 
106 #ifdef TARGET_X86_64
107     uint8_t rex_r;
108     uint8_t rex_x;
109     uint8_t rex_b;
110 #endif
111     bool vex_w; /* used by AVX even on 32-bit processors */
112     bool jmp_opt; /* use direct block chaining for direct jumps */
113     bool repz_opt; /* optimize jumps within repz instructions */
114     bool cc_op_dirty;
115 
116     CCOp cc_op;  /* current CC operation */
117     int mem_index; /* select memory access functions */
118     uint32_t flags; /* all execution flags */
119     int cpuid_features;
120     int cpuid_ext_features;
121     int cpuid_ext2_features;
122     int cpuid_ext3_features;
123     int cpuid_7_0_ebx_features;
124     int cpuid_7_0_ecx_features;
125     int cpuid_xsave_features;
126 
127     /* TCG local temps */
128     TCGv cc_srcT;
129     TCGv A0;
130     TCGv T0;
131     TCGv T1;
132 
133     /* TCG local register indexes (only used inside old micro ops) */
134     TCGv tmp0;
135     TCGv tmp4;
136     TCGv_i32 tmp2_i32;
137     TCGv_i32 tmp3_i32;
138     TCGv_i64 tmp1_i64;
139 
140     sigjmp_buf jmpbuf;
141     TCGOp *prev_insn_end;
142 } DisasContext;
143 
144 #define DISAS_EOB_ONLY         DISAS_TARGET_0
145 #define DISAS_EOB_NEXT         DISAS_TARGET_1
146 #define DISAS_EOB_INHIBIT_IRQ  DISAS_TARGET_2
147 #define DISAS_JUMP             DISAS_TARGET_3
148 
149 /* The environment in which user-only runs is constrained. */
150 #ifdef CONFIG_USER_ONLY
151 #define PE(S)     true
152 #define CPL(S)    3
153 #define IOPL(S)   0
154 #define SVME(S)   false
155 #define GUEST(S)  false
156 #else
157 #define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
158 #define CPL(S)    ((S)->cpl)
159 #define IOPL(S)   ((S)->iopl)
160 #define SVME(S)   (((S)->flags & HF_SVME_MASK) != 0)
161 #define GUEST(S)  (((S)->flags & HF_GUEST_MASK) != 0)
162 #endif
163 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
164 #define VM86(S)   false
165 #define CODE32(S) true
166 #define SS32(S)   true
167 #define ADDSEG(S) false
168 #else
169 #define VM86(S)   (((S)->flags & HF_VM_MASK) != 0)
170 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
171 #define SS32(S)   (((S)->flags & HF_SS32_MASK) != 0)
172 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0)
173 #endif
174 #if !defined(TARGET_X86_64)
175 #define CODE64(S) false
176 #elif defined(CONFIG_USER_ONLY)
177 #define CODE64(S) true
178 #else
179 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
180 #endif
181 #if defined(CONFIG_USER_ONLY) || defined(TARGET_X86_64)
182 #define LMA(S)    (((S)->flags & HF_LMA_MASK) != 0)
183 #else
184 #define LMA(S)    false
185 #endif
186 
187 #ifdef TARGET_X86_64
188 #define REX_PREFIX(S)  (((S)->prefix & PREFIX_REX) != 0)
189 #define REX_W(S)       ((S)->vex_w)
190 #define REX_R(S)       ((S)->rex_r + 0)
191 #define REX_X(S)       ((S)->rex_x + 0)
192 #define REX_B(S)       ((S)->rex_b + 0)
193 #else
194 #define REX_PREFIX(S)  false
195 #define REX_W(S)       false
196 #define REX_R(S)       0
197 #define REX_X(S)       0
198 #define REX_B(S)       0
199 #endif
200 
201 /*
202  * Many sysemu-only helpers are not reachable for user-only.
203  * Define stub generators here, so that we need not either sprinkle
204  * ifdefs through the translator, nor provide the helper function.
205  */
206 #define STUB_HELPER(NAME, ...) \
207     static inline void gen_helper_##NAME(__VA_ARGS__) \
208     { qemu_build_not_reached(); }
209 
210 #ifdef CONFIG_USER_ONLY
211 STUB_HELPER(clgi, TCGv_env env)
212 STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
213 STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
214 STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port)
215 STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port)
216 STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port)
217 STUB_HELPER(monitor, TCGv_env env, TCGv addr)
218 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
219 STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
220 STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
221 STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
222 STUB_HELPER(rdmsr, TCGv_env env)
223 STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg)
224 STUB_HELPER(get_dr, TCGv ret, TCGv_env env, TCGv_i32 reg)
225 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
226 STUB_HELPER(stgi, TCGv_env env)
227 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type)
228 STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag)
229 STUB_HELPER(vmmcall, TCGv_env env)
230 STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs)
231 STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag)
232 STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val)
233 STUB_HELPER(wrmsr, TCGv_env env)
234 #endif
235 
236 static void gen_eob(DisasContext *s);
237 static void gen_jr(DisasContext *s);
238 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num);
239 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num);
240 static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
241 static void gen_exception_gpf(DisasContext *s);
242 
243 /* i386 arith/logic operations */
244 enum {
245     OP_ADDL,
246     OP_ORL,
247     OP_ADCL,
248     OP_SBBL,
249     OP_ANDL,
250     OP_SUBL,
251     OP_XORL,
252     OP_CMPL,
253 };
254 
255 /* i386 shift ops */
256 enum {
257     OP_ROL,
258     OP_ROR,
259     OP_RCL,
260     OP_RCR,
261     OP_SHL,
262     OP_SHR,
263     OP_SHL1, /* undocumented */
264     OP_SAR = 7,
265 };
266 
267 enum {
268     JCC_O,
269     JCC_B,
270     JCC_Z,
271     JCC_BE,
272     JCC_S,
273     JCC_P,
274     JCC_L,
275     JCC_LE,
276 };
277 
278 enum {
279     /* I386 int registers */
280     OR_EAX,   /* MUST be even numbered */
281     OR_ECX,
282     OR_EDX,
283     OR_EBX,
284     OR_ESP,
285     OR_EBP,
286     OR_ESI,
287     OR_EDI,
288 
289     OR_TMP0 = 16,    /* temporary operand register */
290     OR_TMP1,
291     OR_A0, /* temporary register used when doing address evaluation */
292 };
293 
294 enum {
295     USES_CC_DST  = 1,
296     USES_CC_SRC  = 2,
297     USES_CC_SRC2 = 4,
298     USES_CC_SRCT = 8,
299 };
300 
301 /* Bit set if the global variable is live after setting CC_OP to X.  */
302 static const uint8_t cc_op_live[CC_OP_NB] = {
303     [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
304     [CC_OP_EFLAGS] = USES_CC_SRC,
305     [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
306     [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
307     [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
308     [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
309     [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
310     [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
311     [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
312     [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
313     [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
314     [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
315     [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
316     [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
317     [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
318     [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
319     [CC_OP_CLR] = 0,
320     [CC_OP_POPCNT] = USES_CC_SRC,
321 };
322 
set_cc_op(DisasContext * s,CCOp op)323 static void set_cc_op(DisasContext *s, CCOp op)
324 {
325     int dead;
326 
327     if (s->cc_op == op) {
328         return;
329     }
330 
331     /* Discard CC computation that will no longer be used.  */
332     dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
333     if (dead & USES_CC_DST) {
334         tcg_gen_discard_tl(cpu_cc_dst);
335     }
336     if (dead & USES_CC_SRC) {
337         tcg_gen_discard_tl(cpu_cc_src);
338     }
339     if (dead & USES_CC_SRC2) {
340         tcg_gen_discard_tl(cpu_cc_src2);
341     }
342     if (dead & USES_CC_SRCT) {
343         tcg_gen_discard_tl(s->cc_srcT);
344     }
345 
346     if (op == CC_OP_DYNAMIC) {
347         /* The DYNAMIC setting is translator only, and should never be
348            stored.  Thus we always consider it clean.  */
349         s->cc_op_dirty = false;
350     } else {
351         /* Discard any computed CC_OP value (see shifts).  */
352         if (s->cc_op == CC_OP_DYNAMIC) {
353             tcg_gen_discard_i32(cpu_cc_op);
354         }
355         s->cc_op_dirty = true;
356     }
357     s->cc_op = op;
358 }
359 
gen_update_cc_op(DisasContext * s)360 static void gen_update_cc_op(DisasContext *s)
361 {
362     if (s->cc_op_dirty) {
363         tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
364         s->cc_op_dirty = false;
365     }
366 }
367 
368 #ifdef TARGET_X86_64
369 
370 #define NB_OP_SIZES 4
371 
372 #else /* !TARGET_X86_64 */
373 
374 #define NB_OP_SIZES 3
375 
376 #endif /* !TARGET_X86_64 */
377 
378 #if HOST_BIG_ENDIAN
379 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
380 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
381 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
382 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
383 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
384 #else
385 #define REG_B_OFFSET 0
386 #define REG_H_OFFSET 1
387 #define REG_W_OFFSET 0
388 #define REG_L_OFFSET 0
389 #define REG_LH_OFFSET 4
390 #endif
391 
392 /* In instruction encodings for byte register accesses the
393  * register number usually indicates "low 8 bits of register N";
394  * however there are some special cases where N 4..7 indicates
395  * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
396  * true for this special case, false otherwise.
397  */
byte_reg_is_xH(DisasContext * s,int reg)398 static inline bool byte_reg_is_xH(DisasContext *s, int reg)
399 {
400     /* Any time the REX prefix is present, byte registers are uniform */
401     if (reg < 4 || REX_PREFIX(s)) {
402         return false;
403     }
404     return true;
405 }
406 
407 /* Select the size of a push/pop operation.  */
mo_pushpop(DisasContext * s,MemOp ot)408 static inline MemOp mo_pushpop(DisasContext *s, MemOp ot)
409 {
410     if (CODE64(s)) {
411         return ot == MO_16 ? MO_16 : MO_64;
412     } else {
413         return ot;
414     }
415 }
416 
417 /* Select the size of the stack pointer.  */
mo_stacksize(DisasContext * s)418 static inline MemOp mo_stacksize(DisasContext *s)
419 {
420     return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
421 }
422 
423 /* Select only size 64 else 32.  Used for SSE operand sizes.  */
mo_64_32(MemOp ot)424 static inline MemOp mo_64_32(MemOp ot)
425 {
426 #ifdef TARGET_X86_64
427     return ot == MO_64 ? MO_64 : MO_32;
428 #else
429     return MO_32;
430 #endif
431 }
432 
433 /* Select size 8 if lsb of B is clear, else OT.  Used for decoding
434    byte vs word opcodes.  */
mo_b_d(int b,MemOp ot)435 static inline MemOp mo_b_d(int b, MemOp ot)
436 {
437     return b & 1 ? ot : MO_8;
438 }
439 
440 /* Select size 8 if lsb of B is clear, else OT capped at 32.
441    Used for decoding operand size of port opcodes.  */
mo_b_d32(int b,MemOp ot)442 static inline MemOp mo_b_d32(int b, MemOp ot)
443 {
444     return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
445 }
446 
447 /* Compute the result of writing t0 to the OT-sized register REG.
448  *
449  * If DEST is NULL, store the result into the register and return the
450  * register's TCGv.
451  *
452  * If DEST is not NULL, store the result into DEST and return the
453  * register's TCGv.
454  */
gen_op_deposit_reg_v(DisasContext * s,MemOp ot,int reg,TCGv dest,TCGv t0)455 static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest, TCGv t0)
456 {
457     switch(ot) {
458     case MO_8:
459         if (byte_reg_is_xH(s, reg)) {
460             dest = dest ? dest : cpu_regs[reg - 4];
461             tcg_gen_deposit_tl(dest, cpu_regs[reg - 4], t0, 8, 8);
462             return cpu_regs[reg - 4];
463         }
464         dest = dest ? dest : cpu_regs[reg];
465         tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 8);
466         break;
467     case MO_16:
468         dest = dest ? dest : cpu_regs[reg];
469         tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 16);
470         break;
471     case MO_32:
472         /* For x86_64, this sets the higher half of register to zero.
473            For i386, this is equivalent to a mov. */
474         dest = dest ? dest : cpu_regs[reg];
475         tcg_gen_ext32u_tl(dest, t0);
476         break;
477 #ifdef TARGET_X86_64
478     case MO_64:
479         dest = dest ? dest : cpu_regs[reg];
480         tcg_gen_mov_tl(dest, t0);
481         break;
482 #endif
483     default:
484         g_assert_not_reached();
485     }
486     return cpu_regs[reg];
487 }
488 
gen_op_mov_reg_v(DisasContext * s,MemOp ot,int reg,TCGv t0)489 static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0)
490 {
491     gen_op_deposit_reg_v(s, ot, reg, NULL, t0);
492 }
493 
494 static inline
gen_op_mov_v_reg(DisasContext * s,MemOp ot,TCGv t0,int reg)495 void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg)
496 {
497     if (ot == MO_8 && byte_reg_is_xH(s, reg)) {
498         tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
499     } else {
500         tcg_gen_mov_tl(t0, cpu_regs[reg]);
501     }
502 }
503 
gen_add_A0_im(DisasContext * s,int val)504 static void gen_add_A0_im(DisasContext *s, int val)
505 {
506     tcg_gen_addi_tl(s->A0, s->A0, val);
507     if (!CODE64(s)) {
508         tcg_gen_ext32u_tl(s->A0, s->A0);
509     }
510 }
511 
gen_op_jmp_v(DisasContext * s,TCGv dest)512 static inline void gen_op_jmp_v(DisasContext *s, TCGv dest)
513 {
514     tcg_gen_mov_tl(cpu_eip, dest);
515     s->pc_save = -1;
516 }
517 
518 static inline
gen_op_add_reg_im(DisasContext * s,MemOp size,int reg,int32_t val)519 void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val)
520 {
521     tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val);
522     gen_op_mov_reg_v(s, size, reg, s->tmp0);
523 }
524 
gen_op_add_reg_T0(DisasContext * s,MemOp size,int reg)525 static inline void gen_op_add_reg_T0(DisasContext *s, MemOp size, int reg)
526 {
527     tcg_gen_add_tl(s->tmp0, cpu_regs[reg], s->T0);
528     gen_op_mov_reg_v(s, size, reg, s->tmp0);
529 }
530 
gen_op_ld_v(DisasContext * s,int idx,TCGv t0,TCGv a0)531 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
532 {
533     tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
534 }
535 
gen_op_st_v(DisasContext * s,int idx,TCGv t0,TCGv a0)536 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
537 {
538     tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
539 }
540 
gen_op_st_rm_T0_A0(DisasContext * s,int idx,int d)541 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
542 {
543     if (d == OR_TMP0) {
544         gen_op_st_v(s, idx, s->T0, s->A0);
545     } else {
546         gen_op_mov_reg_v(s, idx, d, s->T0);
547     }
548 }
549 
gen_update_eip_cur(DisasContext * s)550 static void gen_update_eip_cur(DisasContext *s)
551 {
552     assert(s->pc_save != -1);
553     if (tb_cflags(s->base.tb) & CF_PCREL) {
554         tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save);
555     } else if (CODE64(s)) {
556         tcg_gen_movi_tl(cpu_eip, s->base.pc_next);
557     } else {
558         tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->base.pc_next - s->cs_base));
559     }
560     s->pc_save = s->base.pc_next;
561 }
562 
gen_update_eip_next(DisasContext * s)563 static void gen_update_eip_next(DisasContext *s)
564 {
565     assert(s->pc_save != -1);
566     if (tb_cflags(s->base.tb) & CF_PCREL) {
567         tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save);
568     } else if (CODE64(s)) {
569         tcg_gen_movi_tl(cpu_eip, s->pc);
570     } else {
571         tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->pc - s->cs_base));
572     }
573     s->pc_save = s->pc;
574 }
575 
cur_insn_len(DisasContext * s)576 static int cur_insn_len(DisasContext *s)
577 {
578     return s->pc - s->base.pc_next;
579 }
580 
cur_insn_len_i32(DisasContext * s)581 static TCGv_i32 cur_insn_len_i32(DisasContext *s)
582 {
583     return tcg_constant_i32(cur_insn_len(s));
584 }
585 
eip_next_i32(DisasContext * s)586 static TCGv_i32 eip_next_i32(DisasContext *s)
587 {
588     assert(s->pc_save != -1);
589     /*
590      * This function has two users: lcall_real (always 16-bit mode), and
591      * iret_protected (16, 32, or 64-bit mode).  IRET only uses the value
592      * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is
593      * why passing a 32-bit value isn't broken.  To avoid using this where
594      * we shouldn't, return -1 in 64-bit mode so that execution goes into
595      * the weeds quickly.
596      */
597     if (CODE64(s)) {
598         return tcg_constant_i32(-1);
599     }
600     if (tb_cflags(s->base.tb) & CF_PCREL) {
601         TCGv_i32 ret = tcg_temp_new_i32();
602         tcg_gen_trunc_tl_i32(ret, cpu_eip);
603         tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save);
604         return ret;
605     } else {
606         return tcg_constant_i32(s->pc - s->cs_base);
607     }
608 }
609 
eip_next_tl(DisasContext * s)610 static TCGv eip_next_tl(DisasContext *s)
611 {
612     assert(s->pc_save != -1);
613     if (tb_cflags(s->base.tb) & CF_PCREL) {
614         TCGv ret = tcg_temp_new();
615         tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save);
616         return ret;
617     } else if (CODE64(s)) {
618         return tcg_constant_tl(s->pc);
619     } else {
620         return tcg_constant_tl((uint32_t)(s->pc - s->cs_base));
621     }
622 }
623 
eip_cur_tl(DisasContext * s)624 static TCGv eip_cur_tl(DisasContext *s)
625 {
626     assert(s->pc_save != -1);
627     if (tb_cflags(s->base.tb) & CF_PCREL) {
628         TCGv ret = tcg_temp_new();
629         tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save);
630         return ret;
631     } else if (CODE64(s)) {
632         return tcg_constant_tl(s->base.pc_next);
633     } else {
634         return tcg_constant_tl((uint32_t)(s->base.pc_next - s->cs_base));
635     }
636 }
637 
638 /* Compute SEG:REG into A0.  SEG is selected from the override segment
639    (OVR_SEG) and the default segment (DEF_SEG).  OVR_SEG may be -1 to
640    indicate no override.  */
gen_lea_v_seg(DisasContext * s,MemOp aflag,TCGv a0,int def_seg,int ovr_seg)641 static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0,
642                           int def_seg, int ovr_seg)
643 {
644     switch (aflag) {
645 #ifdef TARGET_X86_64
646     case MO_64:
647         if (ovr_seg < 0) {
648             tcg_gen_mov_tl(s->A0, a0);
649             return;
650         }
651         break;
652 #endif
653     case MO_32:
654         /* 32 bit address */
655         if (ovr_seg < 0 && ADDSEG(s)) {
656             ovr_seg = def_seg;
657         }
658         if (ovr_seg < 0) {
659             tcg_gen_ext32u_tl(s->A0, a0);
660             return;
661         }
662         break;
663     case MO_16:
664         /* 16 bit address */
665         tcg_gen_ext16u_tl(s->A0, a0);
666         a0 = s->A0;
667         if (ovr_seg < 0) {
668             if (ADDSEG(s)) {
669                 ovr_seg = def_seg;
670             } else {
671                 return;
672             }
673         }
674         break;
675     default:
676         g_assert_not_reached();
677     }
678 
679     if (ovr_seg >= 0) {
680         TCGv seg = cpu_seg_base[ovr_seg];
681 
682         if (aflag == MO_64) {
683             tcg_gen_add_tl(s->A0, a0, seg);
684         } else if (CODE64(s)) {
685             tcg_gen_ext32u_tl(s->A0, a0);
686             tcg_gen_add_tl(s->A0, s->A0, seg);
687         } else {
688             tcg_gen_add_tl(s->A0, a0, seg);
689             tcg_gen_ext32u_tl(s->A0, s->A0);
690         }
691     }
692 }
693 
gen_string_movl_A0_ESI(DisasContext * s)694 static inline void gen_string_movl_A0_ESI(DisasContext *s)
695 {
696     gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
697 }
698 
gen_string_movl_A0_EDI(DisasContext * s)699 static inline void gen_string_movl_A0_EDI(DisasContext *s)
700 {
701     gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
702 }
703 
gen_op_movl_T0_Dshift(DisasContext * s,MemOp ot)704 static inline void gen_op_movl_T0_Dshift(DisasContext *s, MemOp ot)
705 {
706     tcg_gen_ld32s_tl(s->T0, tcg_env, offsetof(CPUX86State, df));
707     tcg_gen_shli_tl(s->T0, s->T0, ot);
708 };
709 
gen_ext_tl(TCGv dst,TCGv src,MemOp size,bool sign)710 static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign)
711 {
712     if (size == MO_TL) {
713         return src;
714     }
715     tcg_gen_ext_tl(dst, src, size | (sign ? MO_SIGN : 0));
716     return dst;
717 }
718 
gen_extu(MemOp ot,TCGv reg)719 static void gen_extu(MemOp ot, TCGv reg)
720 {
721     gen_ext_tl(reg, reg, ot, false);
722 }
723 
gen_exts(MemOp ot,TCGv reg)724 static void gen_exts(MemOp ot, TCGv reg)
725 {
726     gen_ext_tl(reg, reg, ot, true);
727 }
728 
gen_op_j_ecx(DisasContext * s,TCGCond cond,TCGLabel * label1)729 static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1)
730 {
731     tcg_gen_mov_tl(s->tmp0, cpu_regs[R_ECX]);
732     gen_extu(s->aflag, s->tmp0);
733     tcg_gen_brcondi_tl(cond, s->tmp0, 0, label1);
734 }
735 
gen_op_jz_ecx(DisasContext * s,TCGLabel * label1)736 static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1)
737 {
738     gen_op_j_ecx(s, TCG_COND_EQ, label1);
739 }
740 
gen_op_jnz_ecx(DisasContext * s,TCGLabel * label1)741 static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1)
742 {
743     gen_op_j_ecx(s, TCG_COND_NE, label1);
744 }
745 
gen_helper_in_func(MemOp ot,TCGv v,TCGv_i32 n)746 static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n)
747 {
748     switch (ot) {
749     case MO_8:
750         gen_helper_inb(v, tcg_env, n);
751         break;
752     case MO_16:
753         gen_helper_inw(v, tcg_env, n);
754         break;
755     case MO_32:
756         gen_helper_inl(v, tcg_env, n);
757         break;
758     default:
759         g_assert_not_reached();
760     }
761 }
762 
gen_helper_out_func(MemOp ot,TCGv_i32 v,TCGv_i32 n)763 static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
764 {
765     switch (ot) {
766     case MO_8:
767         gen_helper_outb(tcg_env, v, n);
768         break;
769     case MO_16:
770         gen_helper_outw(tcg_env, v, n);
771         break;
772     case MO_32:
773         gen_helper_outl(tcg_env, v, n);
774         break;
775     default:
776         g_assert_not_reached();
777     }
778 }
779 
780 /*
781  * Validate that access to [port, port + 1<<ot) is allowed.
782  * Raise #GP, or VMM exit if not.
783  */
gen_check_io(DisasContext * s,MemOp ot,TCGv_i32 port,uint32_t svm_flags)784 static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
785                          uint32_t svm_flags)
786 {
787 #ifdef CONFIG_USER_ONLY
788     /*
789      * We do not implement the ioperm(2) syscall, so the TSS check
790      * will always fail.
791      */
792     gen_exception_gpf(s);
793     return false;
794 #else
795     if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
796         gen_helper_check_io(tcg_env, port, tcg_constant_i32(1 << ot));
797     }
798     if (GUEST(s)) {
799         gen_update_cc_op(s);
800         gen_update_eip_cur(s);
801         if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
802             svm_flags |= SVM_IOIO_REP_MASK;
803         }
804         svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot);
805         gen_helper_svm_check_io(tcg_env, port,
806                                 tcg_constant_i32(svm_flags),
807                                 cur_insn_len_i32(s));
808     }
809     return true;
810 #endif
811 }
812 
gen_movs(DisasContext * s,MemOp ot)813 static void gen_movs(DisasContext *s, MemOp ot)
814 {
815     gen_string_movl_A0_ESI(s);
816     gen_op_ld_v(s, ot, s->T0, s->A0);
817     gen_string_movl_A0_EDI(s);
818     gen_op_st_v(s, ot, s->T0, s->A0);
819     gen_op_movl_T0_Dshift(s, ot);
820     gen_op_add_reg_T0(s, s->aflag, R_ESI);
821     gen_op_add_reg_T0(s, s->aflag, R_EDI);
822 }
823 
gen_op_update1_cc(DisasContext * s)824 static void gen_op_update1_cc(DisasContext *s)
825 {
826     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
827 }
828 
gen_op_update2_cc(DisasContext * s)829 static void gen_op_update2_cc(DisasContext *s)
830 {
831     tcg_gen_mov_tl(cpu_cc_src, s->T1);
832     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
833 }
834 
gen_op_update3_cc(DisasContext * s,TCGv reg)835 static void gen_op_update3_cc(DisasContext *s, TCGv reg)
836 {
837     tcg_gen_mov_tl(cpu_cc_src2, reg);
838     tcg_gen_mov_tl(cpu_cc_src, s->T1);
839     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
840 }
841 
gen_op_testl_T0_T1_cc(DisasContext * s)842 static inline void gen_op_testl_T0_T1_cc(DisasContext *s)
843 {
844     tcg_gen_and_tl(cpu_cc_dst, s->T0, s->T1);
845 }
846 
gen_op_update_neg_cc(DisasContext * s)847 static void gen_op_update_neg_cc(DisasContext *s)
848 {
849     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
850     tcg_gen_neg_tl(cpu_cc_src, s->T0);
851     tcg_gen_movi_tl(s->cc_srcT, 0);
852 }
853 
854 /* compute all eflags to cc_src */
gen_compute_eflags(DisasContext * s)855 static void gen_compute_eflags(DisasContext *s)
856 {
857     TCGv zero, dst, src1, src2;
858     int live, dead;
859 
860     if (s->cc_op == CC_OP_EFLAGS) {
861         return;
862     }
863     if (s->cc_op == CC_OP_CLR) {
864         tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
865         set_cc_op(s, CC_OP_EFLAGS);
866         return;
867     }
868 
869     zero = NULL;
870     dst = cpu_cc_dst;
871     src1 = cpu_cc_src;
872     src2 = cpu_cc_src2;
873 
874     /* Take care to not read values that are not live.  */
875     live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
876     dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
877     if (dead) {
878         zero = tcg_constant_tl(0);
879         if (dead & USES_CC_DST) {
880             dst = zero;
881         }
882         if (dead & USES_CC_SRC) {
883             src1 = zero;
884         }
885         if (dead & USES_CC_SRC2) {
886             src2 = zero;
887         }
888     }
889 
890     gen_update_cc_op(s);
891     gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
892     set_cc_op(s, CC_OP_EFLAGS);
893 }
894 
895 typedef struct CCPrepare {
896     TCGCond cond;
897     TCGv reg;
898     TCGv reg2;
899     target_ulong imm;
900     target_ulong mask;
901     bool use_reg2;
902     bool no_setcond;
903 } CCPrepare;
904 
905 /* compute eflags.C to reg */
gen_prepare_eflags_c(DisasContext * s,TCGv reg)906 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
907 {
908     TCGv t0, t1;
909     int size, shift;
910 
911     switch (s->cc_op) {
912     case CC_OP_SUBB ... CC_OP_SUBQ:
913         /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
914         size = s->cc_op - CC_OP_SUBB;
915         t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
916         /* If no temporary was used, be careful not to alias t1 and t0.  */
917         t0 = t1 == cpu_cc_src ? s->tmp0 : reg;
918         tcg_gen_mov_tl(t0, s->cc_srcT);
919         gen_extu(size, t0);
920         goto add_sub;
921 
922     case CC_OP_ADDB ... CC_OP_ADDQ:
923         /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
924         size = s->cc_op - CC_OP_ADDB;
925         t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
926         t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
927     add_sub:
928         return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
929                              .reg2 = t1, .mask = -1, .use_reg2 = true };
930 
931     case CC_OP_LOGICB ... CC_OP_LOGICQ:
932     case CC_OP_CLR:
933     case CC_OP_POPCNT:
934         return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
935 
936     case CC_OP_INCB ... CC_OP_INCQ:
937     case CC_OP_DECB ... CC_OP_DECQ:
938         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
939                              .mask = -1, .no_setcond = true };
940 
941     case CC_OP_SHLB ... CC_OP_SHLQ:
942         /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
943         size = s->cc_op - CC_OP_SHLB;
944         shift = (8 << size) - 1;
945         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
946                              .mask = (target_ulong)1 << shift };
947 
948     case CC_OP_MULB ... CC_OP_MULQ:
949         return (CCPrepare) { .cond = TCG_COND_NE,
950                              .reg = cpu_cc_src, .mask = -1 };
951 
952     case CC_OP_BMILGB ... CC_OP_BMILGQ:
953         size = s->cc_op - CC_OP_BMILGB;
954         t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
955         return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
956 
957     case CC_OP_ADCX:
958     case CC_OP_ADCOX:
959         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
960                              .mask = -1, .no_setcond = true };
961 
962     case CC_OP_EFLAGS:
963     case CC_OP_SARB ... CC_OP_SARQ:
964         /* CC_SRC & 1 */
965         return (CCPrepare) { .cond = TCG_COND_NE,
966                              .reg = cpu_cc_src, .mask = CC_C };
967 
968     default:
969        /* The need to compute only C from CC_OP_DYNAMIC is important
970           in efficiently implementing e.g. INC at the start of a TB.  */
971        gen_update_cc_op(s);
972        gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
973                                cpu_cc_src2, cpu_cc_op);
974        return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
975                             .mask = -1, .no_setcond = true };
976     }
977 }
978 
979 /* compute eflags.P to reg */
gen_prepare_eflags_p(DisasContext * s,TCGv reg)980 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
981 {
982     gen_compute_eflags(s);
983     return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
984                          .mask = CC_P };
985 }
986 
987 /* compute eflags.S to reg */
gen_prepare_eflags_s(DisasContext * s,TCGv reg)988 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
989 {
990     switch (s->cc_op) {
991     case CC_OP_DYNAMIC:
992         gen_compute_eflags(s);
993         /* FALLTHRU */
994     case CC_OP_EFLAGS:
995     case CC_OP_ADCX:
996     case CC_OP_ADOX:
997     case CC_OP_ADCOX:
998         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
999                              .mask = CC_S };
1000     case CC_OP_CLR:
1001     case CC_OP_POPCNT:
1002         return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
1003     default:
1004         {
1005             MemOp size = (s->cc_op - CC_OP_ADDB) & 3;
1006             TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
1007             return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
1008         }
1009     }
1010 }
1011 
1012 /* compute eflags.O to reg */
gen_prepare_eflags_o(DisasContext * s,TCGv reg)1013 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
1014 {
1015     switch (s->cc_op) {
1016     case CC_OP_ADOX:
1017     case CC_OP_ADCOX:
1018         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
1019                              .mask = -1, .no_setcond = true };
1020     case CC_OP_CLR:
1021     case CC_OP_POPCNT:
1022         return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
1023     default:
1024         gen_compute_eflags(s);
1025         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1026                              .mask = CC_O };
1027     }
1028 }
1029 
1030 /* compute eflags.Z to reg */
gen_prepare_eflags_z(DisasContext * s,TCGv reg)1031 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
1032 {
1033     switch (s->cc_op) {
1034     case CC_OP_DYNAMIC:
1035         gen_compute_eflags(s);
1036         /* FALLTHRU */
1037     case CC_OP_EFLAGS:
1038     case CC_OP_ADCX:
1039     case CC_OP_ADOX:
1040     case CC_OP_ADCOX:
1041         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1042                              .mask = CC_Z };
1043     case CC_OP_CLR:
1044         return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
1045     case CC_OP_POPCNT:
1046         return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src,
1047                              .mask = -1 };
1048     default:
1049         {
1050             MemOp size = (s->cc_op - CC_OP_ADDB) & 3;
1051             TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
1052             return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
1053         }
1054     }
1055 }
1056 
1057 /* perform a conditional store into register 'reg' according to jump opcode
1058    value 'b'. In the fast case, T0 is guaranteed not to be used. */
gen_prepare_cc(DisasContext * s,int b,TCGv reg)1059 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1060 {
1061     int inv, jcc_op, cond;
1062     MemOp size;
1063     CCPrepare cc;
1064     TCGv t0;
1065 
1066     inv = b & 1;
1067     jcc_op = (b >> 1) & 7;
1068 
1069     switch (s->cc_op) {
1070     case CC_OP_SUBB ... CC_OP_SUBQ:
1071         /* We optimize relational operators for the cmp/jcc case.  */
1072         size = s->cc_op - CC_OP_SUBB;
1073         switch (jcc_op) {
1074         case JCC_BE:
1075             tcg_gen_mov_tl(s->tmp4, s->cc_srcT);
1076             gen_extu(size, s->tmp4);
1077             t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
1078             cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->tmp4,
1079                                .reg2 = t0, .mask = -1, .use_reg2 = true };
1080             break;
1081 
1082         case JCC_L:
1083             cond = TCG_COND_LT;
1084             goto fast_jcc_l;
1085         case JCC_LE:
1086             cond = TCG_COND_LE;
1087         fast_jcc_l:
1088             tcg_gen_mov_tl(s->tmp4, s->cc_srcT);
1089             gen_exts(size, s->tmp4);
1090             t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, true);
1091             cc = (CCPrepare) { .cond = cond, .reg = s->tmp4,
1092                                .reg2 = t0, .mask = -1, .use_reg2 = true };
1093             break;
1094 
1095         default:
1096             goto slow_jcc;
1097         }
1098         break;
1099 
1100     default:
1101     slow_jcc:
1102         /* This actually generates good code for JC, JZ and JS.  */
1103         switch (jcc_op) {
1104         case JCC_O:
1105             cc = gen_prepare_eflags_o(s, reg);
1106             break;
1107         case JCC_B:
1108             cc = gen_prepare_eflags_c(s, reg);
1109             break;
1110         case JCC_Z:
1111             cc = gen_prepare_eflags_z(s, reg);
1112             break;
1113         case JCC_BE:
1114             gen_compute_eflags(s);
1115             cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1116                                .mask = CC_Z | CC_C };
1117             break;
1118         case JCC_S:
1119             cc = gen_prepare_eflags_s(s, reg);
1120             break;
1121         case JCC_P:
1122             cc = gen_prepare_eflags_p(s, reg);
1123             break;
1124         case JCC_L:
1125             gen_compute_eflags(s);
1126             if (reg == cpu_cc_src) {
1127                 reg = s->tmp0;
1128             }
1129             tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1130             tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1131             cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1132                                .mask = CC_S };
1133             break;
1134         default:
1135         case JCC_LE:
1136             gen_compute_eflags(s);
1137             if (reg == cpu_cc_src) {
1138                 reg = s->tmp0;
1139             }
1140             tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1141             tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1142             cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1143                                .mask = CC_S | CC_Z };
1144             break;
1145         }
1146         break;
1147     }
1148 
1149     if (inv) {
1150         cc.cond = tcg_invert_cond(cc.cond);
1151     }
1152     return cc;
1153 }
1154 
gen_setcc1(DisasContext * s,int b,TCGv reg)1155 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
1156 {
1157     CCPrepare cc = gen_prepare_cc(s, b, reg);
1158 
1159     if (cc.no_setcond) {
1160         if (cc.cond == TCG_COND_EQ) {
1161             tcg_gen_xori_tl(reg, cc.reg, 1);
1162         } else {
1163             tcg_gen_mov_tl(reg, cc.reg);
1164         }
1165         return;
1166     }
1167 
1168     if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
1169         cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
1170         tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
1171         tcg_gen_andi_tl(reg, reg, 1);
1172         return;
1173     }
1174     if (cc.mask != -1) {
1175         tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1176         cc.reg = reg;
1177     }
1178     if (cc.use_reg2) {
1179         tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1180     } else {
1181         tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1182     }
1183 }
1184 
gen_compute_eflags_c(DisasContext * s,TCGv reg)1185 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1186 {
1187     gen_setcc1(s, JCC_B << 1, reg);
1188 }
1189 
1190 /* generate a conditional jump to label 'l1' according to jump opcode
1191    value 'b'. In the fast case, T0 is guaranteed not to be used. */
gen_jcc1_noeob(DisasContext * s,int b,TCGLabel * l1)1192 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1193 {
1194     CCPrepare cc = gen_prepare_cc(s, b, s->T0);
1195 
1196     if (cc.mask != -1) {
1197         tcg_gen_andi_tl(s->T0, cc.reg, cc.mask);
1198         cc.reg = s->T0;
1199     }
1200     if (cc.use_reg2) {
1201         tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1202     } else {
1203         tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1204     }
1205 }
1206 
1207 /* Generate a conditional jump to label 'l1' according to jump opcode
1208    value 'b'. In the fast case, T0 is guaranteed not to be used.
1209    A translation block must end soon.  */
gen_jcc1(DisasContext * s,int b,TCGLabel * l1)1210 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1211 {
1212     CCPrepare cc = gen_prepare_cc(s, b, s->T0);
1213 
1214     gen_update_cc_op(s);
1215     if (cc.mask != -1) {
1216         tcg_gen_andi_tl(s->T0, cc.reg, cc.mask);
1217         cc.reg = s->T0;
1218     }
1219     set_cc_op(s, CC_OP_DYNAMIC);
1220     if (cc.use_reg2) {
1221         tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1222     } else {
1223         tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1224     }
1225 }
1226 
1227 /* XXX: does not work with gdbstub "ice" single step - not a
1228    serious problem */
gen_jz_ecx_string(DisasContext * s)1229 static TCGLabel *gen_jz_ecx_string(DisasContext *s)
1230 {
1231     TCGLabel *l1 = gen_new_label();
1232     TCGLabel *l2 = gen_new_label();
1233     gen_op_jnz_ecx(s, l1);
1234     gen_set_label(l2);
1235     gen_jmp_rel_csize(s, 0, 1);
1236     gen_set_label(l1);
1237     return l2;
1238 }
1239 
gen_stos(DisasContext * s,MemOp ot)1240 static void gen_stos(DisasContext *s, MemOp ot)
1241 {
1242     gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
1243     gen_string_movl_A0_EDI(s);
1244     gen_op_st_v(s, ot, s->T0, s->A0);
1245     gen_op_movl_T0_Dshift(s, ot);
1246     gen_op_add_reg_T0(s, s->aflag, R_EDI);
1247 }
1248 
gen_lods(DisasContext * s,MemOp ot)1249 static void gen_lods(DisasContext *s, MemOp ot)
1250 {
1251     gen_string_movl_A0_ESI(s);
1252     gen_op_ld_v(s, ot, s->T0, s->A0);
1253     gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
1254     gen_op_movl_T0_Dshift(s, ot);
1255     gen_op_add_reg_T0(s, s->aflag, R_ESI);
1256 }
1257 
gen_scas(DisasContext * s,MemOp ot)1258 static void gen_scas(DisasContext *s, MemOp ot)
1259 {
1260     gen_string_movl_A0_EDI(s);
1261     gen_op_ld_v(s, ot, s->T1, s->A0);
1262     gen_op(s, OP_CMPL, ot, R_EAX);
1263     gen_op_movl_T0_Dshift(s, ot);
1264     gen_op_add_reg_T0(s, s->aflag, R_EDI);
1265 }
1266 
gen_cmps(DisasContext * s,MemOp ot)1267 static void gen_cmps(DisasContext *s, MemOp ot)
1268 {
1269     gen_string_movl_A0_EDI(s);
1270     gen_op_ld_v(s, ot, s->T1, s->A0);
1271     gen_string_movl_A0_ESI(s);
1272     gen_op(s, OP_CMPL, ot, OR_TMP0);
1273     gen_op_movl_T0_Dshift(s, ot);
1274     gen_op_add_reg_T0(s, s->aflag, R_ESI);
1275     gen_op_add_reg_T0(s, s->aflag, R_EDI);
1276 }
1277 
gen_bpt_io(DisasContext * s,TCGv_i32 t_port,int ot)1278 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1279 {
1280     if (s->flags & HF_IOBPT_MASK) {
1281 #ifdef CONFIG_USER_ONLY
1282         /* user-mode cpu should not be in IOBPT mode */
1283         g_assert_not_reached();
1284 #else
1285         TCGv_i32 t_size = tcg_constant_i32(1 << ot);
1286         TCGv t_next = eip_next_tl(s);
1287         gen_helper_bpt_io(tcg_env, t_port, t_size, t_next);
1288 #endif /* CONFIG_USER_ONLY */
1289     }
1290 }
1291 
gen_ins(DisasContext * s,MemOp ot)1292 static void gen_ins(DisasContext *s, MemOp ot)
1293 {
1294     gen_string_movl_A0_EDI(s);
1295     /* Note: we must do this dummy write first to be restartable in
1296        case of page fault. */
1297     tcg_gen_movi_tl(s->T0, 0);
1298     gen_op_st_v(s, ot, s->T0, s->A0);
1299     tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1300     tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1301     gen_helper_in_func(ot, s->T0, s->tmp2_i32);
1302     gen_op_st_v(s, ot, s->T0, s->A0);
1303     gen_op_movl_T0_Dshift(s, ot);
1304     gen_op_add_reg_T0(s, s->aflag, R_EDI);
1305     gen_bpt_io(s, s->tmp2_i32, ot);
1306 }
1307 
gen_outs(DisasContext * s,MemOp ot)1308 static void gen_outs(DisasContext *s, MemOp ot)
1309 {
1310     gen_string_movl_A0_ESI(s);
1311     gen_op_ld_v(s, ot, s->T0, s->A0);
1312 
1313     tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1314     tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1315     tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0);
1316     gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
1317     gen_op_movl_T0_Dshift(s, ot);
1318     gen_op_add_reg_T0(s, s->aflag, R_ESI);
1319     gen_bpt_io(s, s->tmp2_i32, ot);
1320 }
1321 
1322 /* Generate jumps to current or next instruction */
gen_repz(DisasContext * s,MemOp ot,void (* fn)(DisasContext * s,MemOp ot))1323 static void gen_repz(DisasContext *s, MemOp ot,
1324                      void (*fn)(DisasContext *s, MemOp ot))
1325 {
1326     TCGLabel *l2;
1327     gen_update_cc_op(s);
1328     l2 = gen_jz_ecx_string(s);
1329     fn(s, ot);
1330     gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1331     /*
1332      * A loop would cause two single step exceptions if ECX = 1
1333      * before rep string_insn
1334      */
1335     if (s->repz_opt) {
1336         gen_op_jz_ecx(s, l2);
1337     }
1338     gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1339 }
1340 
1341 #define GEN_REPZ(op) \
1342     static inline void gen_repz_ ## op(DisasContext *s, MemOp ot) \
1343     { gen_repz(s, ot, gen_##op); }
1344 
gen_repz2(DisasContext * s,MemOp ot,int nz,void (* fn)(DisasContext * s,MemOp ot))1345 static void gen_repz2(DisasContext *s, MemOp ot, int nz,
1346                       void (*fn)(DisasContext *s, MemOp ot))
1347 {
1348     TCGLabel *l2;
1349     gen_update_cc_op(s);
1350     l2 = gen_jz_ecx_string(s);
1351     fn(s, ot);
1352     gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1353     gen_update_cc_op(s);
1354     gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);
1355     if (s->repz_opt) {
1356         gen_op_jz_ecx(s, l2);
1357     }
1358     gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1359 }
1360 
1361 #define GEN_REPZ2(op) \
1362     static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, int nz) \
1363     { gen_repz2(s, ot, nz, gen_##op); }
1364 
1365 GEN_REPZ(movs)
GEN_REPZ(stos)1366 GEN_REPZ(stos)
1367 GEN_REPZ(lods)
1368 GEN_REPZ(ins)
1369 GEN_REPZ(outs)
1370 GEN_REPZ2(scas)
1371 GEN_REPZ2(cmps)
1372 
1373 static void gen_helper_fp_arith_ST0_FT0(int op)
1374 {
1375     switch (op) {
1376     case 0:
1377         gen_helper_fadd_ST0_FT0(tcg_env);
1378         break;
1379     case 1:
1380         gen_helper_fmul_ST0_FT0(tcg_env);
1381         break;
1382     case 2:
1383         gen_helper_fcom_ST0_FT0(tcg_env);
1384         break;
1385     case 3:
1386         gen_helper_fcom_ST0_FT0(tcg_env);
1387         break;
1388     case 4:
1389         gen_helper_fsub_ST0_FT0(tcg_env);
1390         break;
1391     case 5:
1392         gen_helper_fsubr_ST0_FT0(tcg_env);
1393         break;
1394     case 6:
1395         gen_helper_fdiv_ST0_FT0(tcg_env);
1396         break;
1397     case 7:
1398         gen_helper_fdivr_ST0_FT0(tcg_env);
1399         break;
1400     }
1401 }
1402 
1403 /* NOTE the exception in "r" op ordering */
gen_helper_fp_arith_STN_ST0(int op,int opreg)1404 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1405 {
1406     TCGv_i32 tmp = tcg_constant_i32(opreg);
1407     switch (op) {
1408     case 0:
1409         gen_helper_fadd_STN_ST0(tcg_env, tmp);
1410         break;
1411     case 1:
1412         gen_helper_fmul_STN_ST0(tcg_env, tmp);
1413         break;
1414     case 4:
1415         gen_helper_fsubr_STN_ST0(tcg_env, tmp);
1416         break;
1417     case 5:
1418         gen_helper_fsub_STN_ST0(tcg_env, tmp);
1419         break;
1420     case 6:
1421         gen_helper_fdivr_STN_ST0(tcg_env, tmp);
1422         break;
1423     case 7:
1424         gen_helper_fdiv_STN_ST0(tcg_env, tmp);
1425         break;
1426     }
1427 }
1428 
gen_exception(DisasContext * s,int trapno)1429 static void gen_exception(DisasContext *s, int trapno)
1430 {
1431     gen_update_cc_op(s);
1432     gen_update_eip_cur(s);
1433     gen_helper_raise_exception(tcg_env, tcg_constant_i32(trapno));
1434     s->base.is_jmp = DISAS_NORETURN;
1435 }
1436 
1437 /* Generate #UD for the current instruction.  The assumption here is that
1438    the instruction is known, but it isn't allowed in the current cpu mode.  */
gen_illegal_opcode(DisasContext * s)1439 static void gen_illegal_opcode(DisasContext *s)
1440 {
1441     gen_exception(s, EXCP06_ILLOP);
1442 }
1443 
1444 /* Generate #GP for the current instruction. */
gen_exception_gpf(DisasContext * s)1445 static void gen_exception_gpf(DisasContext *s)
1446 {
1447     gen_exception(s, EXCP0D_GPF);
1448 }
1449 
1450 /* Check for cpl == 0; if not, raise #GP and return false. */
check_cpl0(DisasContext * s)1451 static bool check_cpl0(DisasContext *s)
1452 {
1453     if (CPL(s) == 0) {
1454         return true;
1455     }
1456     gen_exception_gpf(s);
1457     return false;
1458 }
1459 
1460 /* If vm86, check for iopl == 3; if not, raise #GP and return false. */
check_vm86_iopl(DisasContext * s)1461 static bool check_vm86_iopl(DisasContext *s)
1462 {
1463     if (!VM86(s) || IOPL(s) == 3) {
1464         return true;
1465     }
1466     gen_exception_gpf(s);
1467     return false;
1468 }
1469 
1470 /* Check for iopl allowing access; if not, raise #GP and return false. */
check_iopl(DisasContext * s)1471 static bool check_iopl(DisasContext *s)
1472 {
1473     if (VM86(s) ? IOPL(s) == 3 : CPL(s) <= IOPL(s)) {
1474         return true;
1475     }
1476     gen_exception_gpf(s);
1477     return false;
1478 }
1479 
1480 /* if d == OR_TMP0, it means memory operand (address in A0) */
gen_op(DisasContext * s1,int op,MemOp ot,int d)1481 static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
1482 {
1483     /* Invalid lock prefix when destination is not memory or OP_CMPL. */
1484     if ((d != OR_TMP0 || op == OP_CMPL) && s1->prefix & PREFIX_LOCK) {
1485         gen_illegal_opcode(s1);
1486         return;
1487     }
1488 
1489     if (d != OR_TMP0) {
1490         gen_op_mov_v_reg(s1, ot, s1->T0, d);
1491     } else if (!(s1->prefix & PREFIX_LOCK)) {
1492         gen_op_ld_v(s1, ot, s1->T0, s1->A0);
1493     }
1494     switch(op) {
1495     case OP_ADCL:
1496         gen_compute_eflags_c(s1, s1->tmp4);
1497         if (s1->prefix & PREFIX_LOCK) {
1498             tcg_gen_add_tl(s1->T0, s1->tmp4, s1->T1);
1499             tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1500                                         s1->mem_index, ot | MO_LE);
1501         } else {
1502             tcg_gen_add_tl(s1->T0, s1->T0, s1->T1);
1503             tcg_gen_add_tl(s1->T0, s1->T0, s1->tmp4);
1504             gen_op_st_rm_T0_A0(s1, ot, d);
1505         }
1506         gen_op_update3_cc(s1, s1->tmp4);
1507         set_cc_op(s1, CC_OP_ADCB + ot);
1508         break;
1509     case OP_SBBL:
1510         gen_compute_eflags_c(s1, s1->tmp4);
1511         if (s1->prefix & PREFIX_LOCK) {
1512             tcg_gen_add_tl(s1->T0, s1->T1, s1->tmp4);
1513             tcg_gen_neg_tl(s1->T0, s1->T0);
1514             tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1515                                         s1->mem_index, ot | MO_LE);
1516         } else {
1517             tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1);
1518             tcg_gen_sub_tl(s1->T0, s1->T0, s1->tmp4);
1519             gen_op_st_rm_T0_A0(s1, ot, d);
1520         }
1521         gen_op_update3_cc(s1, s1->tmp4);
1522         set_cc_op(s1, CC_OP_SBBB + ot);
1523         break;
1524     case OP_ADDL:
1525         if (s1->prefix & PREFIX_LOCK) {
1526             tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T1,
1527                                         s1->mem_index, ot | MO_LE);
1528         } else {
1529             tcg_gen_add_tl(s1->T0, s1->T0, s1->T1);
1530             gen_op_st_rm_T0_A0(s1, ot, d);
1531         }
1532         gen_op_update2_cc(s1);
1533         set_cc_op(s1, CC_OP_ADDB + ot);
1534         break;
1535     case OP_SUBL:
1536         if (s1->prefix & PREFIX_LOCK) {
1537             tcg_gen_neg_tl(s1->T0, s1->T1);
1538             tcg_gen_atomic_fetch_add_tl(s1->cc_srcT, s1->A0, s1->T0,
1539                                         s1->mem_index, ot | MO_LE);
1540             tcg_gen_sub_tl(s1->T0, s1->cc_srcT, s1->T1);
1541         } else {
1542             tcg_gen_mov_tl(s1->cc_srcT, s1->T0);
1543             tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1);
1544             gen_op_st_rm_T0_A0(s1, ot, d);
1545         }
1546         gen_op_update2_cc(s1);
1547         set_cc_op(s1, CC_OP_SUBB + ot);
1548         break;
1549     default:
1550     case OP_ANDL:
1551         if (s1->prefix & PREFIX_LOCK) {
1552             tcg_gen_atomic_and_fetch_tl(s1->T0, s1->A0, s1->T1,
1553                                         s1->mem_index, ot | MO_LE);
1554         } else {
1555             tcg_gen_and_tl(s1->T0, s1->T0, s1->T1);
1556             gen_op_st_rm_T0_A0(s1, ot, d);
1557         }
1558         gen_op_update1_cc(s1);
1559         set_cc_op(s1, CC_OP_LOGICB + ot);
1560         break;
1561     case OP_ORL:
1562         if (s1->prefix & PREFIX_LOCK) {
1563             tcg_gen_atomic_or_fetch_tl(s1->T0, s1->A0, s1->T1,
1564                                        s1->mem_index, ot | MO_LE);
1565         } else {
1566             tcg_gen_or_tl(s1->T0, s1->T0, s1->T1);
1567             gen_op_st_rm_T0_A0(s1, ot, d);
1568         }
1569         gen_op_update1_cc(s1);
1570         set_cc_op(s1, CC_OP_LOGICB + ot);
1571         break;
1572     case OP_XORL:
1573         if (s1->prefix & PREFIX_LOCK) {
1574             tcg_gen_atomic_xor_fetch_tl(s1->T0, s1->A0, s1->T1,
1575                                         s1->mem_index, ot | MO_LE);
1576         } else {
1577             tcg_gen_xor_tl(s1->T0, s1->T0, s1->T1);
1578             gen_op_st_rm_T0_A0(s1, ot, d);
1579         }
1580         gen_op_update1_cc(s1);
1581         set_cc_op(s1, CC_OP_LOGICB + ot);
1582         break;
1583     case OP_CMPL:
1584         tcg_gen_mov_tl(cpu_cc_src, s1->T1);
1585         tcg_gen_mov_tl(s1->cc_srcT, s1->T0);
1586         tcg_gen_sub_tl(cpu_cc_dst, s1->T0, s1->T1);
1587         set_cc_op(s1, CC_OP_SUBB + ot);
1588         break;
1589     }
1590 }
1591 
1592 /* if d == OR_TMP0, it means memory operand (address in A0) */
gen_inc(DisasContext * s1,MemOp ot,int d,int c)1593 static void gen_inc(DisasContext *s1, MemOp ot, int d, int c)
1594 {
1595     if (s1->prefix & PREFIX_LOCK) {
1596         if (d != OR_TMP0) {
1597             /* Lock prefix when destination is not memory */
1598             gen_illegal_opcode(s1);
1599             return;
1600         }
1601         tcg_gen_movi_tl(s1->T0, c > 0 ? 1 : -1);
1602         tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1603                                     s1->mem_index, ot | MO_LE);
1604     } else {
1605         if (d != OR_TMP0) {
1606             gen_op_mov_v_reg(s1, ot, s1->T0, d);
1607         } else {
1608             gen_op_ld_v(s1, ot, s1->T0, s1->A0);
1609         }
1610         tcg_gen_addi_tl(s1->T0, s1->T0, (c > 0 ? 1 : -1));
1611         gen_op_st_rm_T0_A0(s1, ot, d);
1612     }
1613 
1614     gen_compute_eflags_c(s1, cpu_cc_src);
1615     tcg_gen_mov_tl(cpu_cc_dst, s1->T0);
1616     set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1617 }
1618 
gen_shift_flags(DisasContext * s,MemOp ot,TCGv result,TCGv shm1,TCGv count,bool is_right)1619 static void gen_shift_flags(DisasContext *s, MemOp ot, TCGv result,
1620                             TCGv shm1, TCGv count, bool is_right)
1621 {
1622     TCGv_i32 z32, s32, oldop;
1623     TCGv z_tl;
1624 
1625     /* Store the results into the CC variables.  If we know that the
1626        variable must be dead, store unconditionally.  Otherwise we'll
1627        need to not disrupt the current contents.  */
1628     z_tl = tcg_constant_tl(0);
1629     if (cc_op_live[s->cc_op] & USES_CC_DST) {
1630         tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1631                            result, cpu_cc_dst);
1632     } else {
1633         tcg_gen_mov_tl(cpu_cc_dst, result);
1634     }
1635     if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1636         tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1637                            shm1, cpu_cc_src);
1638     } else {
1639         tcg_gen_mov_tl(cpu_cc_src, shm1);
1640     }
1641 
1642     /* Get the two potential CC_OP values into temporaries.  */
1643     tcg_gen_movi_i32(s->tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1644     if (s->cc_op == CC_OP_DYNAMIC) {
1645         oldop = cpu_cc_op;
1646     } else {
1647         tcg_gen_movi_i32(s->tmp3_i32, s->cc_op);
1648         oldop = s->tmp3_i32;
1649     }
1650 
1651     /* Conditionally store the CC_OP value.  */
1652     z32 = tcg_constant_i32(0);
1653     s32 = tcg_temp_new_i32();
1654     tcg_gen_trunc_tl_i32(s32, count);
1655     tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, s->tmp2_i32, oldop);
1656 
1657     /* The CC_OP value is no longer predictable.  */
1658     set_cc_op(s, CC_OP_DYNAMIC);
1659 }
1660 
gen_shift_rm_T1(DisasContext * s,MemOp ot,int op1,int is_right,int is_arith)1661 static void gen_shift_rm_T1(DisasContext *s, MemOp ot, int op1,
1662                             int is_right, int is_arith)
1663 {
1664     target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1665 
1666     /* load */
1667     if (op1 == OR_TMP0) {
1668         gen_op_ld_v(s, ot, s->T0, s->A0);
1669     } else {
1670         gen_op_mov_v_reg(s, ot, s->T0, op1);
1671     }
1672 
1673     tcg_gen_andi_tl(s->T1, s->T1, mask);
1674     tcg_gen_subi_tl(s->tmp0, s->T1, 1);
1675 
1676     if (is_right) {
1677         if (is_arith) {
1678             gen_exts(ot, s->T0);
1679             tcg_gen_sar_tl(s->tmp0, s->T0, s->tmp0);
1680             tcg_gen_sar_tl(s->T0, s->T0, s->T1);
1681         } else {
1682             gen_extu(ot, s->T0);
1683             tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0);
1684             tcg_gen_shr_tl(s->T0, s->T0, s->T1);
1685         }
1686     } else {
1687         tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0);
1688         tcg_gen_shl_tl(s->T0, s->T0, s->T1);
1689     }
1690 
1691     /* store */
1692     gen_op_st_rm_T0_A0(s, ot, op1);
1693 
1694     gen_shift_flags(s, ot, s->T0, s->tmp0, s->T1, is_right);
1695 }
1696 
gen_shift_rm_im(DisasContext * s,MemOp ot,int op1,int op2,int is_right,int is_arith)1697 static void gen_shift_rm_im(DisasContext *s, MemOp ot, int op1, int op2,
1698                             int is_right, int is_arith)
1699 {
1700     int mask = (ot == MO_64 ? 0x3f : 0x1f);
1701 
1702     /* load */
1703     if (op1 == OR_TMP0)
1704         gen_op_ld_v(s, ot, s->T0, s->A0);
1705     else
1706         gen_op_mov_v_reg(s, ot, s->T0, op1);
1707 
1708     op2 &= mask;
1709     if (op2 != 0) {
1710         if (is_right) {
1711             if (is_arith) {
1712                 gen_exts(ot, s->T0);
1713                 tcg_gen_sari_tl(s->tmp4, s->T0, op2 - 1);
1714                 tcg_gen_sari_tl(s->T0, s->T0, op2);
1715             } else {
1716                 gen_extu(ot, s->T0);
1717                 tcg_gen_shri_tl(s->tmp4, s->T0, op2 - 1);
1718                 tcg_gen_shri_tl(s->T0, s->T0, op2);
1719             }
1720         } else {
1721             tcg_gen_shli_tl(s->tmp4, s->T0, op2 - 1);
1722             tcg_gen_shli_tl(s->T0, s->T0, op2);
1723         }
1724     }
1725 
1726     /* store */
1727     gen_op_st_rm_T0_A0(s, ot, op1);
1728 
1729     /* update eflags if non zero shift */
1730     if (op2 != 0) {
1731         tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
1732         tcg_gen_mov_tl(cpu_cc_dst, s->T0);
1733         set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1734     }
1735 }
1736 
gen_rot_rm_T1(DisasContext * s,MemOp ot,int op1,int is_right)1737 static void gen_rot_rm_T1(DisasContext *s, MemOp ot, int op1, int is_right)
1738 {
1739     target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1740     TCGv_i32 t0, t1;
1741 
1742     /* load */
1743     if (op1 == OR_TMP0) {
1744         gen_op_ld_v(s, ot, s->T0, s->A0);
1745     } else {
1746         gen_op_mov_v_reg(s, ot, s->T0, op1);
1747     }
1748 
1749     tcg_gen_andi_tl(s->T1, s->T1, mask);
1750 
1751     switch (ot) {
1752     case MO_8:
1753         /* Replicate the 8-bit input so that a 32-bit rotate works.  */
1754         tcg_gen_ext8u_tl(s->T0, s->T0);
1755         tcg_gen_muli_tl(s->T0, s->T0, 0x01010101);
1756         goto do_long;
1757     case MO_16:
1758         /* Replicate the 16-bit input so that a 32-bit rotate works.  */
1759         tcg_gen_deposit_tl(s->T0, s->T0, s->T0, 16, 16);
1760         goto do_long;
1761     do_long:
1762 #ifdef TARGET_X86_64
1763     case MO_32:
1764         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
1765         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
1766         if (is_right) {
1767             tcg_gen_rotr_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
1768         } else {
1769             tcg_gen_rotl_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
1770         }
1771         tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
1772         break;
1773 #endif
1774     default:
1775         if (is_right) {
1776             tcg_gen_rotr_tl(s->T0, s->T0, s->T1);
1777         } else {
1778             tcg_gen_rotl_tl(s->T0, s->T0, s->T1);
1779         }
1780         break;
1781     }
1782 
1783     /* store */
1784     gen_op_st_rm_T0_A0(s, ot, op1);
1785 
1786     /* We'll need the flags computed into CC_SRC.  */
1787     gen_compute_eflags(s);
1788 
1789     /* The value that was "rotated out" is now present at the other end
1790        of the word.  Compute C into CC_DST and O into CC_SRC2.  Note that
1791        since we've computed the flags into CC_SRC, these variables are
1792        currently dead.  */
1793     if (is_right) {
1794         tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1);
1795         tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask);
1796         tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1797     } else {
1798         tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask);
1799         tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1);
1800     }
1801     tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1802     tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1803 
1804     /* Now conditionally store the new CC_OP value.  If the shift count
1805        is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1806        Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1807        exactly as we computed above.  */
1808     t0 = tcg_constant_i32(0);
1809     t1 = tcg_temp_new_i32();
1810     tcg_gen_trunc_tl_i32(t1, s->T1);
1811     tcg_gen_movi_i32(s->tmp2_i32, CC_OP_ADCOX);
1812     tcg_gen_movi_i32(s->tmp3_i32, CC_OP_EFLAGS);
1813     tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1814                         s->tmp2_i32, s->tmp3_i32);
1815 
1816     /* The CC_OP value is no longer predictable.  */
1817     set_cc_op(s, CC_OP_DYNAMIC);
1818 }
1819 
gen_rot_rm_im(DisasContext * s,MemOp ot,int op1,int op2,int is_right)1820 static void gen_rot_rm_im(DisasContext *s, MemOp ot, int op1, int op2,
1821                           int is_right)
1822 {
1823     int mask = (ot == MO_64 ? 0x3f : 0x1f);
1824     int shift;
1825 
1826     /* load */
1827     if (op1 == OR_TMP0) {
1828         gen_op_ld_v(s, ot, s->T0, s->A0);
1829     } else {
1830         gen_op_mov_v_reg(s, ot, s->T0, op1);
1831     }
1832 
1833     op2 &= mask;
1834     if (op2 != 0) {
1835         switch (ot) {
1836 #ifdef TARGET_X86_64
1837         case MO_32:
1838             tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
1839             if (is_right) {
1840                 tcg_gen_rotri_i32(s->tmp2_i32, s->tmp2_i32, op2);
1841             } else {
1842                 tcg_gen_rotli_i32(s->tmp2_i32, s->tmp2_i32, op2);
1843             }
1844             tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
1845             break;
1846 #endif
1847         default:
1848             if (is_right) {
1849                 tcg_gen_rotri_tl(s->T0, s->T0, op2);
1850             } else {
1851                 tcg_gen_rotli_tl(s->T0, s->T0, op2);
1852             }
1853             break;
1854         case MO_8:
1855             mask = 7;
1856             goto do_shifts;
1857         case MO_16:
1858             mask = 15;
1859         do_shifts:
1860             shift = op2 & mask;
1861             if (is_right) {
1862                 shift = mask + 1 - shift;
1863             }
1864             gen_extu(ot, s->T0);
1865             tcg_gen_shli_tl(s->tmp0, s->T0, shift);
1866             tcg_gen_shri_tl(s->T0, s->T0, mask + 1 - shift);
1867             tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
1868             break;
1869         }
1870     }
1871 
1872     /* store */
1873     gen_op_st_rm_T0_A0(s, ot, op1);
1874 
1875     if (op2 != 0) {
1876         /* Compute the flags into CC_SRC.  */
1877         gen_compute_eflags(s);
1878 
1879         /* The value that was "rotated out" is now present at the other end
1880            of the word.  Compute C into CC_DST and O into CC_SRC2.  Note that
1881            since we've computed the flags into CC_SRC, these variables are
1882            currently dead.  */
1883         if (is_right) {
1884             tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1);
1885             tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask);
1886             tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1887         } else {
1888             tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask);
1889             tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1);
1890         }
1891         tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1892         tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1893         set_cc_op(s, CC_OP_ADCOX);
1894     }
1895 }
1896 
1897 /* XXX: add faster immediate = 1 case */
gen_rotc_rm_T1(DisasContext * s,MemOp ot,int op1,int is_right)1898 static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1,
1899                            int is_right)
1900 {
1901     gen_compute_eflags(s);
1902     assert(s->cc_op == CC_OP_EFLAGS);
1903 
1904     /* load */
1905     if (op1 == OR_TMP0)
1906         gen_op_ld_v(s, ot, s->T0, s->A0);
1907     else
1908         gen_op_mov_v_reg(s, ot, s->T0, op1);
1909 
1910     if (is_right) {
1911         switch (ot) {
1912         case MO_8:
1913             gen_helper_rcrb(s->T0, tcg_env, s->T0, s->T1);
1914             break;
1915         case MO_16:
1916             gen_helper_rcrw(s->T0, tcg_env, s->T0, s->T1);
1917             break;
1918         case MO_32:
1919             gen_helper_rcrl(s->T0, tcg_env, s->T0, s->T1);
1920             break;
1921 #ifdef TARGET_X86_64
1922         case MO_64:
1923             gen_helper_rcrq(s->T0, tcg_env, s->T0, s->T1);
1924             break;
1925 #endif
1926         default:
1927             g_assert_not_reached();
1928         }
1929     } else {
1930         switch (ot) {
1931         case MO_8:
1932             gen_helper_rclb(s->T0, tcg_env, s->T0, s->T1);
1933             break;
1934         case MO_16:
1935             gen_helper_rclw(s->T0, tcg_env, s->T0, s->T1);
1936             break;
1937         case MO_32:
1938             gen_helper_rcll(s->T0, tcg_env, s->T0, s->T1);
1939             break;
1940 #ifdef TARGET_X86_64
1941         case MO_64:
1942             gen_helper_rclq(s->T0, tcg_env, s->T0, s->T1);
1943             break;
1944 #endif
1945         default:
1946             g_assert_not_reached();
1947         }
1948     }
1949     /* store */
1950     gen_op_st_rm_T0_A0(s, ot, op1);
1951 }
1952 
1953 /* XXX: add faster immediate case */
gen_shiftd_rm_T1(DisasContext * s,MemOp ot,int op1,bool is_right,TCGv count_in)1954 static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1,
1955                              bool is_right, TCGv count_in)
1956 {
1957     target_ulong mask = (ot == MO_64 ? 63 : 31);
1958     TCGv count;
1959 
1960     /* load */
1961     if (op1 == OR_TMP0) {
1962         gen_op_ld_v(s, ot, s->T0, s->A0);
1963     } else {
1964         gen_op_mov_v_reg(s, ot, s->T0, op1);
1965     }
1966 
1967     count = tcg_temp_new();
1968     tcg_gen_andi_tl(count, count_in, mask);
1969 
1970     switch (ot) {
1971     case MO_16:
1972         /* Note: we implement the Intel behaviour for shift count > 16.
1973            This means "shrdw C, B, A" shifts A:B:A >> C.  Build the B:A
1974            portion by constructing it as a 32-bit value.  */
1975         if (is_right) {
1976             tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16);
1977             tcg_gen_mov_tl(s->T1, s->T0);
1978             tcg_gen_mov_tl(s->T0, s->tmp0);
1979         } else {
1980             tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16);
1981         }
1982         /*
1983          * If TARGET_X86_64 defined then fall through into MO_32 case,
1984          * otherwise fall through default case.
1985          */
1986     case MO_32:
1987 #ifdef TARGET_X86_64
1988         /* Concatenate the two 32-bit values and use a 64-bit shift.  */
1989         tcg_gen_subi_tl(s->tmp0, count, 1);
1990         if (is_right) {
1991             tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1);
1992             tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0);
1993             tcg_gen_shr_i64(s->T0, s->T0, count);
1994         } else {
1995             tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0);
1996             tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0);
1997             tcg_gen_shl_i64(s->T0, s->T0, count);
1998             tcg_gen_shri_i64(s->tmp0, s->tmp0, 32);
1999             tcg_gen_shri_i64(s->T0, s->T0, 32);
2000         }
2001         break;
2002 #endif
2003     default:
2004         tcg_gen_subi_tl(s->tmp0, count, 1);
2005         if (is_right) {
2006             tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0);
2007 
2008             tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
2009             tcg_gen_shr_tl(s->T0, s->T0, count);
2010             tcg_gen_shl_tl(s->T1, s->T1, s->tmp4);
2011         } else {
2012             tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0);
2013             if (ot == MO_16) {
2014                 /* Only needed if count > 16, for Intel behaviour.  */
2015                 tcg_gen_subfi_tl(s->tmp4, 33, count);
2016                 tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4);
2017                 tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4);
2018             }
2019 
2020             tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
2021             tcg_gen_shl_tl(s->T0, s->T0, count);
2022             tcg_gen_shr_tl(s->T1, s->T1, s->tmp4);
2023         }
2024         tcg_gen_movi_tl(s->tmp4, 0);
2025         tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4,
2026                            s->tmp4, s->T1);
2027         tcg_gen_or_tl(s->T0, s->T0, s->T1);
2028         break;
2029     }
2030 
2031     /* store */
2032     gen_op_st_rm_T0_A0(s, ot, op1);
2033 
2034     gen_shift_flags(s, ot, s->T0, s->tmp0, count, is_right);
2035 }
2036 
gen_shift(DisasContext * s1,int op,MemOp ot,int d,int s)2037 static void gen_shift(DisasContext *s1, int op, MemOp ot, int d, int s)
2038 {
2039     if (s != OR_TMP1)
2040         gen_op_mov_v_reg(s1, ot, s1->T1, s);
2041     switch(op) {
2042     case OP_ROL:
2043         gen_rot_rm_T1(s1, ot, d, 0);
2044         break;
2045     case OP_ROR:
2046         gen_rot_rm_T1(s1, ot, d, 1);
2047         break;
2048     case OP_SHL:
2049     case OP_SHL1:
2050         gen_shift_rm_T1(s1, ot, d, 0, 0);
2051         break;
2052     case OP_SHR:
2053         gen_shift_rm_T1(s1, ot, d, 1, 0);
2054         break;
2055     case OP_SAR:
2056         gen_shift_rm_T1(s1, ot, d, 1, 1);
2057         break;
2058     case OP_RCL:
2059         gen_rotc_rm_T1(s1, ot, d, 0);
2060         break;
2061     case OP_RCR:
2062         gen_rotc_rm_T1(s1, ot, d, 1);
2063         break;
2064     }
2065 }
2066 
gen_shifti(DisasContext * s1,int op,MemOp ot,int d,int c)2067 static void gen_shifti(DisasContext *s1, int op, MemOp ot, int d, int c)
2068 {
2069     switch(op) {
2070     case OP_ROL:
2071         gen_rot_rm_im(s1, ot, d, c, 0);
2072         break;
2073     case OP_ROR:
2074         gen_rot_rm_im(s1, ot, d, c, 1);
2075         break;
2076     case OP_SHL:
2077     case OP_SHL1:
2078         gen_shift_rm_im(s1, ot, d, c, 0, 0);
2079         break;
2080     case OP_SHR:
2081         gen_shift_rm_im(s1, ot, d, c, 1, 0);
2082         break;
2083     case OP_SAR:
2084         gen_shift_rm_im(s1, ot, d, c, 1, 1);
2085         break;
2086     default:
2087         /* currently not optimized */
2088         tcg_gen_movi_tl(s1->T1, c);
2089         gen_shift(s1, op, ot, d, OR_TMP1);
2090         break;
2091     }
2092 }
2093 
2094 #define X86_MAX_INSN_LENGTH 15
2095 
advance_pc(CPUX86State * env,DisasContext * s,int num_bytes)2096 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
2097 {
2098     uint64_t pc = s->pc;
2099 
2100     /* This is a subsequent insn that crosses a page boundary.  */
2101     if (s->base.num_insns > 1 &&
2102         !is_same_page(&s->base, s->pc + num_bytes - 1)) {
2103         siglongjmp(s->jmpbuf, 2);
2104     }
2105 
2106     s->pc += num_bytes;
2107     if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) {
2108         /* If the instruction's 16th byte is on a different page than the 1st, a
2109          * page fault on the second page wins over the general protection fault
2110          * caused by the instruction being too long.
2111          * This can happen even if the operand is only one byte long!
2112          */
2113         if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) {
2114             volatile uint8_t unused =
2115                 cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK);
2116             (void) unused;
2117         }
2118         siglongjmp(s->jmpbuf, 1);
2119     }
2120 
2121     return pc;
2122 }
2123 
x86_ldub_code(CPUX86State * env,DisasContext * s)2124 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
2125 {
2126     return translator_ldub(env, &s->base, advance_pc(env, s, 1));
2127 }
2128 
x86_ldsw_code(CPUX86State * env,DisasContext * s)2129 static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
2130 {
2131     return translator_lduw(env, &s->base, advance_pc(env, s, 2));
2132 }
2133 
x86_lduw_code(CPUX86State * env,DisasContext * s)2134 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
2135 {
2136     return translator_lduw(env, &s->base, advance_pc(env, s, 2));
2137 }
2138 
x86_ldl_code(CPUX86State * env,DisasContext * s)2139 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
2140 {
2141     return translator_ldl(env, &s->base, advance_pc(env, s, 4));
2142 }
2143 
2144 #ifdef TARGET_X86_64
x86_ldq_code(CPUX86State * env,DisasContext * s)2145 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
2146 {
2147     return translator_ldq(env, &s->base, advance_pc(env, s, 8));
2148 }
2149 #endif
2150 
2151 /* Decompose an address.  */
2152 
2153 typedef struct AddressParts {
2154     int def_seg;
2155     int base;
2156     int index;
2157     int scale;
2158     target_long disp;
2159 } AddressParts;
2160 
gen_lea_modrm_0(CPUX86State * env,DisasContext * s,int modrm)2161 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
2162                                     int modrm)
2163 {
2164     int def_seg, base, index, scale, mod, rm;
2165     target_long disp;
2166     bool havesib;
2167 
2168     def_seg = R_DS;
2169     index = -1;
2170     scale = 0;
2171     disp = 0;
2172 
2173     mod = (modrm >> 6) & 3;
2174     rm = modrm & 7;
2175     base = rm | REX_B(s);
2176 
2177     if (mod == 3) {
2178         /* Normally filtered out earlier, but including this path
2179            simplifies multi-byte nop, as well as bndcl, bndcu, bndcn.  */
2180         goto done;
2181     }
2182 
2183     switch (s->aflag) {
2184     case MO_64:
2185     case MO_32:
2186         havesib = 0;
2187         if (rm == 4) {
2188             int code = x86_ldub_code(env, s);
2189             scale = (code >> 6) & 3;
2190             index = ((code >> 3) & 7) | REX_X(s);
2191             if (index == 4) {
2192                 index = -1;  /* no index */
2193             }
2194             base = (code & 7) | REX_B(s);
2195             havesib = 1;
2196         }
2197 
2198         switch (mod) {
2199         case 0:
2200             if ((base & 7) == 5) {
2201                 base = -1;
2202                 disp = (int32_t)x86_ldl_code(env, s);
2203                 if (CODE64(s) && !havesib) {
2204                     base = -2;
2205                     disp += s->pc + s->rip_offset;
2206                 }
2207             }
2208             break;
2209         case 1:
2210             disp = (int8_t)x86_ldub_code(env, s);
2211             break;
2212         default:
2213         case 2:
2214             disp = (int32_t)x86_ldl_code(env, s);
2215             break;
2216         }
2217 
2218         /* For correct popl handling with esp.  */
2219         if (base == R_ESP && s->popl_esp_hack) {
2220             disp += s->popl_esp_hack;
2221         }
2222         if (base == R_EBP || base == R_ESP) {
2223             def_seg = R_SS;
2224         }
2225         break;
2226 
2227     case MO_16:
2228         if (mod == 0) {
2229             if (rm == 6) {
2230                 base = -1;
2231                 disp = x86_lduw_code(env, s);
2232                 break;
2233             }
2234         } else if (mod == 1) {
2235             disp = (int8_t)x86_ldub_code(env, s);
2236         } else {
2237             disp = (int16_t)x86_lduw_code(env, s);
2238         }
2239 
2240         switch (rm) {
2241         case 0:
2242             base = R_EBX;
2243             index = R_ESI;
2244             break;
2245         case 1:
2246             base = R_EBX;
2247             index = R_EDI;
2248             break;
2249         case 2:
2250             base = R_EBP;
2251             index = R_ESI;
2252             def_seg = R_SS;
2253             break;
2254         case 3:
2255             base = R_EBP;
2256             index = R_EDI;
2257             def_seg = R_SS;
2258             break;
2259         case 4:
2260             base = R_ESI;
2261             break;
2262         case 5:
2263             base = R_EDI;
2264             break;
2265         case 6:
2266             base = R_EBP;
2267             def_seg = R_SS;
2268             break;
2269         default:
2270         case 7:
2271             base = R_EBX;
2272             break;
2273         }
2274         break;
2275 
2276     default:
2277         g_assert_not_reached();
2278     }
2279 
2280  done:
2281     return (AddressParts){ def_seg, base, index, scale, disp };
2282 }
2283 
2284 /* Compute the address, with a minimum number of TCG ops.  */
gen_lea_modrm_1(DisasContext * s,AddressParts a,bool is_vsib)2285 static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib)
2286 {
2287     TCGv ea = NULL;
2288 
2289     if (a.index >= 0 && !is_vsib) {
2290         if (a.scale == 0) {
2291             ea = cpu_regs[a.index];
2292         } else {
2293             tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale);
2294             ea = s->A0;
2295         }
2296         if (a.base >= 0) {
2297             tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]);
2298             ea = s->A0;
2299         }
2300     } else if (a.base >= 0) {
2301         ea = cpu_regs[a.base];
2302     }
2303     if (!ea) {
2304         if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) {
2305             /* With cpu_eip ~= pc_save, the expression is pc-relative. */
2306             tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save);
2307         } else {
2308             tcg_gen_movi_tl(s->A0, a.disp);
2309         }
2310         ea = s->A0;
2311     } else if (a.disp != 0) {
2312         tcg_gen_addi_tl(s->A0, ea, a.disp);
2313         ea = s->A0;
2314     }
2315 
2316     return ea;
2317 }
2318 
gen_lea_modrm(CPUX86State * env,DisasContext * s,int modrm)2319 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2320 {
2321     AddressParts a = gen_lea_modrm_0(env, s, modrm);
2322     TCGv ea = gen_lea_modrm_1(s, a, false);
2323     gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2324 }
2325 
gen_nop_modrm(CPUX86State * env,DisasContext * s,int modrm)2326 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2327 {
2328     (void)gen_lea_modrm_0(env, s, modrm);
2329 }
2330 
2331 /* Used for BNDCL, BNDCU, BNDCN.  */
gen_bndck(CPUX86State * env,DisasContext * s,int modrm,TCGCond cond,TCGv_i64 bndv)2332 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2333                       TCGCond cond, TCGv_i64 bndv)
2334 {
2335     AddressParts a = gen_lea_modrm_0(env, s, modrm);
2336     TCGv ea = gen_lea_modrm_1(s, a, false);
2337 
2338     tcg_gen_extu_tl_i64(s->tmp1_i64, ea);
2339     if (!CODE64(s)) {
2340         tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64);
2341     }
2342     tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv);
2343     tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64);
2344     gen_helper_bndck(tcg_env, s->tmp2_i32);
2345 }
2346 
2347 /* used for LEA and MOV AX, mem */
gen_add_A0_ds_seg(DisasContext * s)2348 static void gen_add_A0_ds_seg(DisasContext *s)
2349 {
2350     gen_lea_v_seg(s, s->aflag, s->A0, R_DS, s->override);
2351 }
2352 
2353 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2354    OR_TMP0 */
gen_ldst_modrm(CPUX86State * env,DisasContext * s,int modrm,MemOp ot,int reg,int is_store)2355 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2356                            MemOp ot, int reg, int is_store)
2357 {
2358     int mod, rm;
2359 
2360     mod = (modrm >> 6) & 3;
2361     rm = (modrm & 7) | REX_B(s);
2362     if (mod == 3) {
2363         if (is_store) {
2364             if (reg != OR_TMP0)
2365                 gen_op_mov_v_reg(s, ot, s->T0, reg);
2366             gen_op_mov_reg_v(s, ot, rm, s->T0);
2367         } else {
2368             gen_op_mov_v_reg(s, ot, s->T0, rm);
2369             if (reg != OR_TMP0)
2370                 gen_op_mov_reg_v(s, ot, reg, s->T0);
2371         }
2372     } else {
2373         gen_lea_modrm(env, s, modrm);
2374         if (is_store) {
2375             if (reg != OR_TMP0)
2376                 gen_op_mov_v_reg(s, ot, s->T0, reg);
2377             gen_op_st_v(s, ot, s->T0, s->A0);
2378         } else {
2379             gen_op_ld_v(s, ot, s->T0, s->A0);
2380             if (reg != OR_TMP0)
2381                 gen_op_mov_reg_v(s, ot, reg, s->T0);
2382         }
2383     }
2384 }
2385 
insn_get_addr(CPUX86State * env,DisasContext * s,MemOp ot)2386 static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot)
2387 {
2388     target_ulong ret;
2389 
2390     switch (ot) {
2391     case MO_8:
2392         ret = x86_ldub_code(env, s);
2393         break;
2394     case MO_16:
2395         ret = x86_lduw_code(env, s);
2396         break;
2397     case MO_32:
2398         ret = x86_ldl_code(env, s);
2399         break;
2400 #ifdef TARGET_X86_64
2401     case MO_64:
2402         ret = x86_ldq_code(env, s);
2403         break;
2404 #endif
2405     default:
2406         g_assert_not_reached();
2407     }
2408     return ret;
2409 }
2410 
insn_get(CPUX86State * env,DisasContext * s,MemOp ot)2411 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot)
2412 {
2413     uint32_t ret;
2414 
2415     switch (ot) {
2416     case MO_8:
2417         ret = x86_ldub_code(env, s);
2418         break;
2419     case MO_16:
2420         ret = x86_lduw_code(env, s);
2421         break;
2422     case MO_32:
2423 #ifdef TARGET_X86_64
2424     case MO_64:
2425 #endif
2426         ret = x86_ldl_code(env, s);
2427         break;
2428     default:
2429         g_assert_not_reached();
2430     }
2431     return ret;
2432 }
2433 
insn_get_signed(CPUX86State * env,DisasContext * s,MemOp ot)2434 static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot)
2435 {
2436     target_long ret;
2437 
2438     switch (ot) {
2439     case MO_8:
2440         ret = (int8_t) x86_ldub_code(env, s);
2441         break;
2442     case MO_16:
2443         ret = (int16_t) x86_lduw_code(env, s);
2444         break;
2445     case MO_32:
2446         ret = (int32_t) x86_ldl_code(env, s);
2447         break;
2448 #ifdef TARGET_X86_64
2449     case MO_64:
2450         ret = x86_ldq_code(env, s);
2451         break;
2452 #endif
2453     default:
2454         g_assert_not_reached();
2455     }
2456     return ret;
2457 }
2458 
insn_const_size(MemOp ot)2459 static inline int insn_const_size(MemOp ot)
2460 {
2461     if (ot <= MO_32) {
2462         return 1 << ot;
2463     } else {
2464         return 4;
2465     }
2466 }
2467 
gen_jcc(DisasContext * s,int b,int diff)2468 static void gen_jcc(DisasContext *s, int b, int diff)
2469 {
2470     TCGLabel *l1 = gen_new_label();
2471 
2472     gen_jcc1(s, b, l1);
2473     gen_jmp_rel_csize(s, 0, 1);
2474     gen_set_label(l1);
2475     gen_jmp_rel(s, s->dflag, diff, 0);
2476 }
2477 
gen_cmovcc1(CPUX86State * env,DisasContext * s,MemOp ot,int b,int modrm,int reg)2478 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, MemOp ot, int b,
2479                         int modrm, int reg)
2480 {
2481     CCPrepare cc;
2482 
2483     gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2484 
2485     cc = gen_prepare_cc(s, b, s->T1);
2486     if (cc.mask != -1) {
2487         TCGv t0 = tcg_temp_new();
2488         tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2489         cc.reg = t0;
2490     }
2491     if (!cc.use_reg2) {
2492         cc.reg2 = tcg_constant_tl(cc.imm);
2493     }
2494 
2495     tcg_gen_movcond_tl(cc.cond, s->T0, cc.reg, cc.reg2,
2496                        s->T0, cpu_regs[reg]);
2497     gen_op_mov_reg_v(s, ot, reg, s->T0);
2498 }
2499 
gen_op_movl_T0_seg(DisasContext * s,X86Seg seg_reg)2500 static inline void gen_op_movl_T0_seg(DisasContext *s, X86Seg seg_reg)
2501 {
2502     tcg_gen_ld32u_tl(s->T0, tcg_env,
2503                      offsetof(CPUX86State,segs[seg_reg].selector));
2504 }
2505 
gen_op_movl_seg_T0_vm(DisasContext * s,X86Seg seg_reg)2506 static inline void gen_op_movl_seg_T0_vm(DisasContext *s, X86Seg seg_reg)
2507 {
2508     tcg_gen_ext16u_tl(s->T0, s->T0);
2509     tcg_gen_st32_tl(s->T0, tcg_env,
2510                     offsetof(CPUX86State,segs[seg_reg].selector));
2511     tcg_gen_shli_tl(cpu_seg_base[seg_reg], s->T0, 4);
2512 }
2513 
2514 /* move T0 to seg_reg and compute if the CPU state may change. Never
2515    call this function with seg_reg == R_CS */
gen_movl_seg_T0(DisasContext * s,X86Seg seg_reg)2516 static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
2517 {
2518     if (PE(s) && !VM86(s)) {
2519         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
2520         gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32);
2521         /* abort translation because the addseg value may change or
2522            because ss32 may change. For R_SS, translation must always
2523            stop as a special handling must be done to disable hardware
2524            interrupts for the next instruction */
2525         if (seg_reg == R_SS) {
2526             s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
2527         } else if (CODE32(s) && seg_reg < R_FS) {
2528             s->base.is_jmp = DISAS_EOB_NEXT;
2529         }
2530     } else {
2531         gen_op_movl_seg_T0_vm(s, seg_reg);
2532         if (seg_reg == R_SS) {
2533             s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
2534         }
2535     }
2536 }
2537 
gen_svm_check_intercept(DisasContext * s,uint32_t type)2538 static void gen_svm_check_intercept(DisasContext *s, uint32_t type)
2539 {
2540     /* no SVM activated; fast case */
2541     if (likely(!GUEST(s))) {
2542         return;
2543     }
2544     gen_helper_svm_check_intercept(tcg_env, tcg_constant_i32(type));
2545 }
2546 
gen_stack_update(DisasContext * s,int addend)2547 static inline void gen_stack_update(DisasContext *s, int addend)
2548 {
2549     gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend);
2550 }
2551 
2552 /* Generate a push. It depends on ss32, addseg and dflag.  */
gen_push_v(DisasContext * s,TCGv val)2553 static void gen_push_v(DisasContext *s, TCGv val)
2554 {
2555     MemOp d_ot = mo_pushpop(s, s->dflag);
2556     MemOp a_ot = mo_stacksize(s);
2557     int size = 1 << d_ot;
2558     TCGv new_esp = s->A0;
2559 
2560     tcg_gen_subi_tl(s->A0, cpu_regs[R_ESP], size);
2561 
2562     if (!CODE64(s)) {
2563         if (ADDSEG(s)) {
2564             new_esp = s->tmp4;
2565             tcg_gen_mov_tl(new_esp, s->A0);
2566         }
2567         gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2568     }
2569 
2570     gen_op_st_v(s, d_ot, val, s->A0);
2571     gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp);
2572 }
2573 
2574 /* two step pop is necessary for precise exceptions */
gen_pop_T0(DisasContext * s)2575 static MemOp gen_pop_T0(DisasContext *s)
2576 {
2577     MemOp d_ot = mo_pushpop(s, s->dflag);
2578 
2579     gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2580     gen_op_ld_v(s, d_ot, s->T0, s->A0);
2581 
2582     return d_ot;
2583 }
2584 
gen_pop_update(DisasContext * s,MemOp ot)2585 static inline void gen_pop_update(DisasContext *s, MemOp ot)
2586 {
2587     gen_stack_update(s, 1 << ot);
2588 }
2589 
gen_stack_A0(DisasContext * s)2590 static inline void gen_stack_A0(DisasContext *s)
2591 {
2592     gen_lea_v_seg(s, SS32(s) ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2593 }
2594 
gen_pusha(DisasContext * s)2595 static void gen_pusha(DisasContext *s)
2596 {
2597     MemOp s_ot = SS32(s) ? MO_32 : MO_16;
2598     MemOp d_ot = s->dflag;
2599     int size = 1 << d_ot;
2600     int i;
2601 
2602     for (i = 0; i < 8; i++) {
2603         tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], (i - 8) * size);
2604         gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1);
2605         gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0);
2606     }
2607 
2608     gen_stack_update(s, -8 * size);
2609 }
2610 
gen_popa(DisasContext * s)2611 static void gen_popa(DisasContext *s)
2612 {
2613     MemOp s_ot = SS32(s) ? MO_32 : MO_16;
2614     MemOp d_ot = s->dflag;
2615     int size = 1 << d_ot;
2616     int i;
2617 
2618     for (i = 0; i < 8; i++) {
2619         /* ESP is not reloaded */
2620         if (7 - i == R_ESP) {
2621             continue;
2622         }
2623         tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], i * size);
2624         gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1);
2625         gen_op_ld_v(s, d_ot, s->T0, s->A0);
2626         gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0);
2627     }
2628 
2629     gen_stack_update(s, 8 * size);
2630 }
2631 
gen_enter(DisasContext * s,int esp_addend,int level)2632 static void gen_enter(DisasContext *s, int esp_addend, int level)
2633 {
2634     MemOp d_ot = mo_pushpop(s, s->dflag);
2635     MemOp a_ot = CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
2636     int size = 1 << d_ot;
2637 
2638     /* Push BP; compute FrameTemp into T1.  */
2639     tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size);
2640     gen_lea_v_seg(s, a_ot, s->T1, R_SS, -1);
2641     gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0);
2642 
2643     level &= 31;
2644     if (level != 0) {
2645         int i;
2646 
2647         /* Copy level-1 pointers from the previous frame.  */
2648         for (i = 1; i < level; ++i) {
2649             tcg_gen_subi_tl(s->A0, cpu_regs[R_EBP], size * i);
2650             gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2651             gen_op_ld_v(s, d_ot, s->tmp0, s->A0);
2652 
2653             tcg_gen_subi_tl(s->A0, s->T1, size * i);
2654             gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2655             gen_op_st_v(s, d_ot, s->tmp0, s->A0);
2656         }
2657 
2658         /* Push the current FrameTemp as the last level.  */
2659         tcg_gen_subi_tl(s->A0, s->T1, size * level);
2660         gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2661         gen_op_st_v(s, d_ot, s->T1, s->A0);
2662     }
2663 
2664     /* Copy the FrameTemp value to EBP.  */
2665     gen_op_mov_reg_v(s, a_ot, R_EBP, s->T1);
2666 
2667     /* Compute the final value of ESP.  */
2668     tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level);
2669     gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2670 }
2671 
gen_leave(DisasContext * s)2672 static void gen_leave(DisasContext *s)
2673 {
2674     MemOp d_ot = mo_pushpop(s, s->dflag);
2675     MemOp a_ot = mo_stacksize(s);
2676 
2677     gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2678     gen_op_ld_v(s, d_ot, s->T0, s->A0);
2679 
2680     tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot);
2681 
2682     gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0);
2683     gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2684 }
2685 
2686 /* Similarly, except that the assumption here is that we don't decode
2687    the instruction at all -- either a missing opcode, an unimplemented
2688    feature, or just a bogus instruction stream.  */
gen_unknown_opcode(CPUX86State * env,DisasContext * s)2689 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2690 {
2691     gen_illegal_opcode(s);
2692 
2693     if (qemu_loglevel_mask(LOG_UNIMP)) {
2694         FILE *logfile = qemu_log_trylock();
2695         if (logfile) {
2696             target_ulong pc = s->base.pc_next, end = s->pc;
2697 
2698             fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc);
2699             for (; pc < end; ++pc) {
2700                 fprintf(logfile, " %02x", cpu_ldub_code(env, pc));
2701             }
2702             fprintf(logfile, "\n");
2703             qemu_log_unlock(logfile);
2704         }
2705     }
2706 }
2707 
2708 /* an interrupt is different from an exception because of the
2709    privilege checks */
gen_interrupt(DisasContext * s,int intno)2710 static void gen_interrupt(DisasContext *s, int intno)
2711 {
2712     gen_update_cc_op(s);
2713     gen_update_eip_cur(s);
2714     gen_helper_raise_interrupt(tcg_env, tcg_constant_i32(intno),
2715                                cur_insn_len_i32(s));
2716     s->base.is_jmp = DISAS_NORETURN;
2717 }
2718 
gen_set_hflag(DisasContext * s,uint32_t mask)2719 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2720 {
2721     if ((s->flags & mask) == 0) {
2722         TCGv_i32 t = tcg_temp_new_i32();
2723         tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2724         tcg_gen_ori_i32(t, t, mask);
2725         tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2726         s->flags |= mask;
2727     }
2728 }
2729 
gen_reset_hflag(DisasContext * s,uint32_t mask)2730 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2731 {
2732     if (s->flags & mask) {
2733         TCGv_i32 t = tcg_temp_new_i32();
2734         tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2735         tcg_gen_andi_i32(t, t, ~mask);
2736         tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2737         s->flags &= ~mask;
2738     }
2739 }
2740 
gen_set_eflags(DisasContext * s,target_ulong mask)2741 static void gen_set_eflags(DisasContext *s, target_ulong mask)
2742 {
2743     TCGv t = tcg_temp_new();
2744 
2745     tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2746     tcg_gen_ori_tl(t, t, mask);
2747     tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2748 }
2749 
gen_reset_eflags(DisasContext * s,target_ulong mask)2750 static void gen_reset_eflags(DisasContext *s, target_ulong mask)
2751 {
2752     TCGv t = tcg_temp_new();
2753 
2754     tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2755     tcg_gen_andi_tl(t, t, ~mask);
2756     tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2757 }
2758 
2759 /* Clear BND registers during legacy branches.  */
gen_bnd_jmp(DisasContext * s)2760 static void gen_bnd_jmp(DisasContext *s)
2761 {
2762     /* Clear the registers only if BND prefix is missing, MPX is enabled,
2763        and if the BNDREGs are known to be in use (non-zero) already.
2764        The helper itself will check BNDPRESERVE at runtime.  */
2765     if ((s->prefix & PREFIX_REPNZ) == 0
2766         && (s->flags & HF_MPX_EN_MASK) != 0
2767         && (s->flags & HF_MPX_IU_MASK) != 0) {
2768         gen_helper_bnd_jmp(tcg_env);
2769     }
2770 }
2771 
2772 /* Generate an end of block. Trace exception is also generated if needed.
2773    If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2774    If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2775    S->TF.  This is used by the syscall/sysret insns.  */
2776 static void
do_gen_eob_worker(DisasContext * s,bool inhibit,bool recheck_tf,bool jr)2777 do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
2778 {
2779     gen_update_cc_op(s);
2780 
2781     /* If several instructions disable interrupts, only the first does it.  */
2782     if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2783         gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2784     } else {
2785         gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2786     }
2787 
2788     if (s->base.tb->flags & HF_RF_MASK) {
2789         gen_reset_eflags(s, RF_MASK);
2790     }
2791     if (recheck_tf) {
2792         gen_helper_rechecking_single_step(tcg_env);
2793         tcg_gen_exit_tb(NULL, 0);
2794     } else if (s->flags & HF_TF_MASK) {
2795         gen_helper_single_step(tcg_env);
2796     } else if (jr) {
2797         tcg_gen_lookup_and_goto_ptr();
2798     } else {
2799         tcg_gen_exit_tb(NULL, 0);
2800     }
2801     s->base.is_jmp = DISAS_NORETURN;
2802 }
2803 
2804 static inline void
gen_eob_worker(DisasContext * s,bool inhibit,bool recheck_tf)2805 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2806 {
2807     do_gen_eob_worker(s, inhibit, recheck_tf, false);
2808 }
2809 
2810 /* End of block.
2811    If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.  */
gen_eob_inhibit_irq(DisasContext * s,bool inhibit)2812 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2813 {
2814     gen_eob_worker(s, inhibit, false);
2815 }
2816 
2817 /* End of block, resetting the inhibit irq flag.  */
gen_eob(DisasContext * s)2818 static void gen_eob(DisasContext *s)
2819 {
2820     gen_eob_worker(s, false, false);
2821 }
2822 
2823 /* Jump to register */
gen_jr(DisasContext * s)2824 static void gen_jr(DisasContext *s)
2825 {
2826     do_gen_eob_worker(s, false, false, true);
2827 }
2828 
2829 /* Jump to eip+diff, truncating the result to OT. */
gen_jmp_rel(DisasContext * s,MemOp ot,int diff,int tb_num)2830 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
2831 {
2832     bool use_goto_tb = s->jmp_opt;
2833     target_ulong mask = -1;
2834     target_ulong new_pc = s->pc + diff;
2835     target_ulong new_eip = new_pc - s->cs_base;
2836 
2837     /* In 64-bit mode, operand size is fixed at 64 bits. */
2838     if (!CODE64(s)) {
2839         if (ot == MO_16) {
2840             mask = 0xffff;
2841             if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) {
2842                 use_goto_tb = false;
2843             }
2844         } else {
2845             mask = 0xffffffff;
2846         }
2847     }
2848     new_eip &= mask;
2849 
2850     gen_update_cc_op(s);
2851     set_cc_op(s, CC_OP_DYNAMIC);
2852 
2853     if (tb_cflags(s->base.tb) & CF_PCREL) {
2854         tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save);
2855         /*
2856          * If we can prove the branch does not leave the page and we have
2857          * no extra masking to apply (data16 branch in code32, see above),
2858          * then we have also proven that the addition does not wrap.
2859          */
2860         if (!use_goto_tb || !is_same_page(&s->base, new_pc)) {
2861             tcg_gen_andi_tl(cpu_eip, cpu_eip, mask);
2862             use_goto_tb = false;
2863         }
2864     } else if (!CODE64(s)) {
2865         new_pc = (uint32_t)(new_eip + s->cs_base);
2866     }
2867 
2868     if (use_goto_tb && translator_use_goto_tb(&s->base, new_pc)) {
2869         /* jump to same page: we can use a direct jump */
2870         tcg_gen_goto_tb(tb_num);
2871         if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
2872             tcg_gen_movi_tl(cpu_eip, new_eip);
2873         }
2874         tcg_gen_exit_tb(s->base.tb, tb_num);
2875         s->base.is_jmp = DISAS_NORETURN;
2876     } else {
2877         if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
2878             tcg_gen_movi_tl(cpu_eip, new_eip);
2879         }
2880         if (s->jmp_opt) {
2881             gen_jr(s);   /* jump to another page */
2882         } else {
2883             gen_eob(s);  /* exit to main loop */
2884         }
2885     }
2886 }
2887 
2888 /* Jump to eip+diff, truncating to the current code size. */
gen_jmp_rel_csize(DisasContext * s,int diff,int tb_num)2889 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num)
2890 {
2891     /* CODE64 ignores the OT argument, so we need not consider it. */
2892     gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num);
2893 }
2894 
gen_ldq_env_A0(DisasContext * s,int offset)2895 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2896 {
2897     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2898     tcg_gen_st_i64(s->tmp1_i64, tcg_env, offset);
2899 }
2900 
gen_stq_env_A0(DisasContext * s,int offset)2901 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2902 {
2903     tcg_gen_ld_i64(s->tmp1_i64, tcg_env, offset);
2904     tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2905 }
2906 
gen_ldo_env_A0(DisasContext * s,int offset,bool align)2907 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align)
2908 {
2909     MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX
2910                   ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR);
2911     MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0);
2912     int mem_index = s->mem_index;
2913     TCGv_i128 t = tcg_temp_new_i128();
2914 
2915     tcg_gen_qemu_ld_i128(t, s->A0, mem_index, mop);
2916     tcg_gen_st_i128(t, tcg_env, offset);
2917 }
2918 
gen_sto_env_A0(DisasContext * s,int offset,bool align)2919 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align)
2920 {
2921     MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX
2922                   ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR);
2923     MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0);
2924     int mem_index = s->mem_index;
2925     TCGv_i128 t = tcg_temp_new_i128();
2926 
2927     tcg_gen_ld_i128(t, tcg_env, offset);
2928     tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop);
2929 }
2930 
gen_ldy_env_A0(DisasContext * s,int offset,bool align)2931 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align)
2932 {
2933     MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR;
2934     int mem_index = s->mem_index;
2935     TCGv_i128 t0 = tcg_temp_new_i128();
2936     TCGv_i128 t1 = tcg_temp_new_i128();
2937 
2938     tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0));
2939     tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2940     tcg_gen_qemu_ld_i128(t1, s->tmp0, mem_index, mop);
2941 
2942     tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0)));
2943     tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1)));
2944 }
2945 
gen_sty_env_A0(DisasContext * s,int offset,bool align)2946 static void gen_sty_env_A0(DisasContext *s, int offset, bool align)
2947 {
2948     MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR;
2949     int mem_index = s->mem_index;
2950     TCGv_i128 t = tcg_temp_new_i128();
2951 
2952     tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0)));
2953     tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0));
2954     tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2955     tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1)));
2956     tcg_gen_qemu_st_i128(t, s->tmp0, mem_index, mop);
2957 }
2958 
2959 #include "decode-new.h"
2960 #include "emit.c.inc"
2961 #include "decode-new.c.inc"
2962 
gen_cmpxchg8b(DisasContext * s,CPUX86State * env,int modrm)2963 static void gen_cmpxchg8b(DisasContext *s, CPUX86State *env, int modrm)
2964 {
2965     TCGv_i64 cmp, val, old;
2966     TCGv Z;
2967 
2968     gen_lea_modrm(env, s, modrm);
2969 
2970     cmp = tcg_temp_new_i64();
2971     val = tcg_temp_new_i64();
2972     old = tcg_temp_new_i64();
2973 
2974     /* Construct the comparison values from the register pair. */
2975     tcg_gen_concat_tl_i64(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]);
2976     tcg_gen_concat_tl_i64(val, cpu_regs[R_EBX], cpu_regs[R_ECX]);
2977 
2978     /* Only require atomic with LOCK; non-parallel handled in generator. */
2979     if (s->prefix & PREFIX_LOCK) {
2980         tcg_gen_atomic_cmpxchg_i64(old, s->A0, cmp, val, s->mem_index, MO_TEUQ);
2981     } else {
2982         tcg_gen_nonatomic_cmpxchg_i64(old, s->A0, cmp, val,
2983                                       s->mem_index, MO_TEUQ);
2984     }
2985 
2986     /* Set tmp0 to match the required value of Z. */
2987     tcg_gen_setcond_i64(TCG_COND_EQ, cmp, old, cmp);
2988     Z = tcg_temp_new();
2989     tcg_gen_trunc_i64_tl(Z, cmp);
2990 
2991     /*
2992      * Extract the result values for the register pair.
2993      * For 32-bit, we may do this unconditionally, because on success (Z=1),
2994      * the old value matches the previous value in EDX:EAX.  For x86_64,
2995      * the store must be conditional, because we must leave the source
2996      * registers unchanged on success, and zero-extend the writeback
2997      * on failure (Z=0).
2998      */
2999     if (TARGET_LONG_BITS == 32) {
3000         tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], old);
3001     } else {
3002         TCGv zero = tcg_constant_tl(0);
3003 
3004         tcg_gen_extr_i64_tl(s->T0, s->T1, old);
3005         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EAX], Z, zero,
3006                            s->T0, cpu_regs[R_EAX]);
3007         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EDX], Z, zero,
3008                            s->T1, cpu_regs[R_EDX]);
3009     }
3010 
3011     /* Update Z. */
3012     gen_compute_eflags(s);
3013     tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, Z, ctz32(CC_Z), 1);
3014 }
3015 
3016 #ifdef TARGET_X86_64
gen_cmpxchg16b(DisasContext * s,CPUX86State * env,int modrm)3017 static void gen_cmpxchg16b(DisasContext *s, CPUX86State *env, int modrm)
3018 {
3019     MemOp mop = MO_TE | MO_128 | MO_ALIGN;
3020     TCGv_i64 t0, t1;
3021     TCGv_i128 cmp, val;
3022 
3023     gen_lea_modrm(env, s, modrm);
3024 
3025     cmp = tcg_temp_new_i128();
3026     val = tcg_temp_new_i128();
3027     tcg_gen_concat_i64_i128(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]);
3028     tcg_gen_concat_i64_i128(val, cpu_regs[R_EBX], cpu_regs[R_ECX]);
3029 
3030     /* Only require atomic with LOCK; non-parallel handled in generator. */
3031     if (s->prefix & PREFIX_LOCK) {
3032         tcg_gen_atomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop);
3033     } else {
3034         tcg_gen_nonatomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop);
3035     }
3036 
3037     tcg_gen_extr_i128_i64(s->T0, s->T1, val);
3038 
3039     /* Determine success after the fact. */
3040     t0 = tcg_temp_new_i64();
3041     t1 = tcg_temp_new_i64();
3042     tcg_gen_xor_i64(t0, s->T0, cpu_regs[R_EAX]);
3043     tcg_gen_xor_i64(t1, s->T1, cpu_regs[R_EDX]);
3044     tcg_gen_or_i64(t0, t0, t1);
3045 
3046     /* Update Z. */
3047     gen_compute_eflags(s);
3048     tcg_gen_setcondi_i64(TCG_COND_EQ, t0, t0, 0);
3049     tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, t0, ctz32(CC_Z), 1);
3050 
3051     /*
3052      * Extract the result values for the register pair.  We may do this
3053      * unconditionally, because on success (Z=1), the old value matches
3054      * the previous value in RDX:RAX.
3055      */
3056     tcg_gen_mov_i64(cpu_regs[R_EAX], s->T0);
3057     tcg_gen_mov_i64(cpu_regs[R_EDX], s->T1);
3058 }
3059 #endif
3060 
3061 /* convert one instruction. s->base.is_jmp is set if the translation must
3062    be stopped. Return the next pc value */
disas_insn(DisasContext * s,CPUState * cpu)3063 static bool disas_insn(DisasContext *s, CPUState *cpu)
3064 {
3065     CPUX86State *env = cpu_env(cpu);
3066     int b, prefixes;
3067     int shift;
3068     MemOp ot, aflag, dflag;
3069     int modrm, reg, rm, mod, op, opreg, val;
3070     bool orig_cc_op_dirty = s->cc_op_dirty;
3071     CCOp orig_cc_op = s->cc_op;
3072     target_ulong orig_pc_save = s->pc_save;
3073 
3074     s->pc = s->base.pc_next;
3075     s->override = -1;
3076 #ifdef TARGET_X86_64
3077     s->rex_r = 0;
3078     s->rex_x = 0;
3079     s->rex_b = 0;
3080 #endif
3081     s->rip_offset = 0; /* for relative ip address */
3082     s->vex_l = 0;
3083     s->vex_v = 0;
3084     s->vex_w = false;
3085     switch (sigsetjmp(s->jmpbuf, 0)) {
3086     case 0:
3087         break;
3088     case 1:
3089         gen_exception_gpf(s);
3090         return true;
3091     case 2:
3092         /* Restore state that may affect the next instruction. */
3093         s->pc = s->base.pc_next;
3094         /*
3095          * TODO: These save/restore can be removed after the table-based
3096          * decoder is complete; we will be decoding the insn completely
3097          * before any code generation that might affect these variables.
3098          */
3099         s->cc_op_dirty = orig_cc_op_dirty;
3100         s->cc_op = orig_cc_op;
3101         s->pc_save = orig_pc_save;
3102         /* END TODO */
3103         s->base.num_insns--;
3104         tcg_remove_ops_after(s->prev_insn_end);
3105         s->base.is_jmp = DISAS_TOO_MANY;
3106         return false;
3107     default:
3108         g_assert_not_reached();
3109     }
3110 
3111     prefixes = 0;
3112 
3113  next_byte:
3114     s->prefix = prefixes;
3115     b = x86_ldub_code(env, s);
3116     /* Collect prefixes.  */
3117     switch (b) {
3118     default:
3119         break;
3120     case 0x0f:
3121         b = x86_ldub_code(env, s) + 0x100;
3122         break;
3123     case 0xf3:
3124         prefixes |= PREFIX_REPZ;
3125         prefixes &= ~PREFIX_REPNZ;
3126         goto next_byte;
3127     case 0xf2:
3128         prefixes |= PREFIX_REPNZ;
3129         prefixes &= ~PREFIX_REPZ;
3130         goto next_byte;
3131     case 0xf0:
3132         prefixes |= PREFIX_LOCK;
3133         goto next_byte;
3134     case 0x2e:
3135         s->override = R_CS;
3136         goto next_byte;
3137     case 0x36:
3138         s->override = R_SS;
3139         goto next_byte;
3140     case 0x3e:
3141         s->override = R_DS;
3142         goto next_byte;
3143     case 0x26:
3144         s->override = R_ES;
3145         goto next_byte;
3146     case 0x64:
3147         s->override = R_FS;
3148         goto next_byte;
3149     case 0x65:
3150         s->override = R_GS;
3151         goto next_byte;
3152     case 0x66:
3153         prefixes |= PREFIX_DATA;
3154         goto next_byte;
3155     case 0x67:
3156         prefixes |= PREFIX_ADR;
3157         goto next_byte;
3158 #ifdef TARGET_X86_64
3159     case 0x40 ... 0x4f:
3160         if (CODE64(s)) {
3161             /* REX prefix */
3162             prefixes |= PREFIX_REX;
3163             s->vex_w = (b >> 3) & 1;
3164             s->rex_r = (b & 0x4) << 1;
3165             s->rex_x = (b & 0x2) << 2;
3166             s->rex_b = (b & 0x1) << 3;
3167             goto next_byte;
3168         }
3169         break;
3170 #endif
3171     case 0xc5: /* 2-byte VEX */
3172     case 0xc4: /* 3-byte VEX */
3173         if (CODE32(s) && !VM86(s)) {
3174             int vex2 = x86_ldub_code(env, s);
3175             s->pc--; /* rewind the advance_pc() x86_ldub_code() did */
3176 
3177             if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
3178                 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
3179                    otherwise the instruction is LES or LDS.  */
3180                 break;
3181             }
3182             disas_insn_new(s, cpu, b);
3183             return s->pc;
3184         }
3185         break;
3186     }
3187 
3188     /* Post-process prefixes.  */
3189     if (CODE64(s)) {
3190         /* In 64-bit mode, the default data size is 32-bit.  Select 64-bit
3191            data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
3192            over 0x66 if both are present.  */
3193         dflag = (REX_W(s) ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
3194         /* In 64-bit mode, 0x67 selects 32-bit addressing.  */
3195         aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
3196     } else {
3197         /* In 16/32-bit mode, 0x66 selects the opposite data size.  */
3198         if (CODE32(s) ^ ((prefixes & PREFIX_DATA) != 0)) {
3199             dflag = MO_32;
3200         } else {
3201             dflag = MO_16;
3202         }
3203         /* In 16/32-bit mode, 0x67 selects the opposite addressing.  */
3204         if (CODE32(s) ^ ((prefixes & PREFIX_ADR) != 0)) {
3205             aflag = MO_32;
3206         }  else {
3207             aflag = MO_16;
3208         }
3209     }
3210 
3211     s->prefix = prefixes;
3212     s->aflag = aflag;
3213     s->dflag = dflag;
3214 
3215     /* now check op code */
3216     switch (b) {
3217         /**************************/
3218         /* arith & logic */
3219     case 0x00 ... 0x05:
3220     case 0x08 ... 0x0d:
3221     case 0x10 ... 0x15:
3222     case 0x18 ... 0x1d:
3223     case 0x20 ... 0x25:
3224     case 0x28 ... 0x2d:
3225     case 0x30 ... 0x35:
3226     case 0x38 ... 0x3d:
3227         {
3228             int f;
3229             op = (b >> 3) & 7;
3230             f = (b >> 1) & 3;
3231 
3232             ot = mo_b_d(b, dflag);
3233 
3234             switch(f) {
3235             case 0: /* OP Ev, Gv */
3236                 modrm = x86_ldub_code(env, s);
3237                 reg = ((modrm >> 3) & 7) | REX_R(s);
3238                 mod = (modrm >> 6) & 3;
3239                 rm = (modrm & 7) | REX_B(s);
3240                 if (mod != 3) {
3241                     gen_lea_modrm(env, s, modrm);
3242                     opreg = OR_TMP0;
3243                 } else if (op == OP_XORL && rm == reg) {
3244                 xor_zero:
3245                     /* xor reg, reg optimisation */
3246                     set_cc_op(s, CC_OP_CLR);
3247                     tcg_gen_movi_tl(s->T0, 0);
3248                     gen_op_mov_reg_v(s, ot, reg, s->T0);
3249                     break;
3250                 } else {
3251                     opreg = rm;
3252                 }
3253                 gen_op_mov_v_reg(s, ot, s->T1, reg);
3254                 gen_op(s, op, ot, opreg);
3255                 break;
3256             case 1: /* OP Gv, Ev */
3257                 modrm = x86_ldub_code(env, s);
3258                 mod = (modrm >> 6) & 3;
3259                 reg = ((modrm >> 3) & 7) | REX_R(s);
3260                 rm = (modrm & 7) | REX_B(s);
3261                 if (mod != 3) {
3262                     gen_lea_modrm(env, s, modrm);
3263                     gen_op_ld_v(s, ot, s->T1, s->A0);
3264                 } else if (op == OP_XORL && rm == reg) {
3265                     goto xor_zero;
3266                 } else {
3267                     gen_op_mov_v_reg(s, ot, s->T1, rm);
3268                 }
3269                 gen_op(s, op, ot, reg);
3270                 break;
3271             case 2: /* OP A, Iv */
3272                 val = insn_get(env, s, ot);
3273                 tcg_gen_movi_tl(s->T1, val);
3274                 gen_op(s, op, ot, OR_EAX);
3275                 break;
3276             }
3277         }
3278         break;
3279 
3280     case 0x82:
3281         if (CODE64(s))
3282             goto illegal_op;
3283         /* fall through */
3284     case 0x80: /* GRP1 */
3285     case 0x81:
3286     case 0x83:
3287         {
3288             ot = mo_b_d(b, dflag);
3289 
3290             modrm = x86_ldub_code(env, s);
3291             mod = (modrm >> 6) & 3;
3292             rm = (modrm & 7) | REX_B(s);
3293             op = (modrm >> 3) & 7;
3294 
3295             if (mod != 3) {
3296                 if (b == 0x83)
3297                     s->rip_offset = 1;
3298                 else
3299                     s->rip_offset = insn_const_size(ot);
3300                 gen_lea_modrm(env, s, modrm);
3301                 opreg = OR_TMP0;
3302             } else {
3303                 opreg = rm;
3304             }
3305 
3306             switch(b) {
3307             default:
3308             case 0x80:
3309             case 0x81:
3310             case 0x82:
3311                 val = insn_get(env, s, ot);
3312                 break;
3313             case 0x83:
3314                 val = (int8_t)insn_get(env, s, MO_8);
3315                 break;
3316             }
3317             tcg_gen_movi_tl(s->T1, val);
3318             gen_op(s, op, ot, opreg);
3319         }
3320         break;
3321 
3322         /**************************/
3323         /* inc, dec, and other misc arith */
3324     case 0x40 ... 0x47: /* inc Gv */
3325         ot = dflag;
3326         gen_inc(s, ot, OR_EAX + (b & 7), 1);
3327         break;
3328     case 0x48 ... 0x4f: /* dec Gv */
3329         ot = dflag;
3330         gen_inc(s, ot, OR_EAX + (b & 7), -1);
3331         break;
3332     case 0xf6: /* GRP3 */
3333     case 0xf7:
3334         ot = mo_b_d(b, dflag);
3335 
3336         modrm = x86_ldub_code(env, s);
3337         mod = (modrm >> 6) & 3;
3338         rm = (modrm & 7) | REX_B(s);
3339         op = (modrm >> 3) & 7;
3340         if (mod != 3) {
3341             if (op == 0) {
3342                 s->rip_offset = insn_const_size(ot);
3343             }
3344             gen_lea_modrm(env, s, modrm);
3345             /* For those below that handle locked memory, don't load here.  */
3346             if (!(s->prefix & PREFIX_LOCK)
3347                 || op != 2) {
3348                 gen_op_ld_v(s, ot, s->T0, s->A0);
3349             }
3350         } else {
3351             gen_op_mov_v_reg(s, ot, s->T0, rm);
3352         }
3353 
3354         switch(op) {
3355         case 0: /* test */
3356             val = insn_get(env, s, ot);
3357             tcg_gen_movi_tl(s->T1, val);
3358             gen_op_testl_T0_T1_cc(s);
3359             set_cc_op(s, CC_OP_LOGICB + ot);
3360             break;
3361         case 2: /* not */
3362             if (s->prefix & PREFIX_LOCK) {
3363                 if (mod == 3) {
3364                     goto illegal_op;
3365                 }
3366                 tcg_gen_movi_tl(s->T0, ~0);
3367                 tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0,
3368                                             s->mem_index, ot | MO_LE);
3369             } else {
3370                 tcg_gen_not_tl(s->T0, s->T0);
3371                 if (mod != 3) {
3372                     gen_op_st_v(s, ot, s->T0, s->A0);
3373                 } else {
3374                     gen_op_mov_reg_v(s, ot, rm, s->T0);
3375                 }
3376             }
3377             break;
3378         case 3: /* neg */
3379             if (s->prefix & PREFIX_LOCK) {
3380                 TCGLabel *label1;
3381                 TCGv a0, t0, t1, t2;
3382 
3383                 if (mod == 3) {
3384                     goto illegal_op;
3385                 }
3386                 a0 = s->A0;
3387                 t0 = s->T0;
3388                 label1 = gen_new_label();
3389 
3390                 gen_set_label(label1);
3391                 t1 = tcg_temp_new();
3392                 t2 = tcg_temp_new();
3393                 tcg_gen_mov_tl(t2, t0);
3394                 tcg_gen_neg_tl(t1, t0);
3395                 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
3396                                           s->mem_index, ot | MO_LE);
3397                 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
3398 
3399                 tcg_gen_neg_tl(s->T0, t0);
3400             } else {
3401                 tcg_gen_neg_tl(s->T0, s->T0);
3402                 if (mod != 3) {
3403                     gen_op_st_v(s, ot, s->T0, s->A0);
3404                 } else {
3405                     gen_op_mov_reg_v(s, ot, rm, s->T0);
3406                 }
3407             }
3408             gen_op_update_neg_cc(s);
3409             set_cc_op(s, CC_OP_SUBB + ot);
3410             break;
3411         case 4: /* mul */
3412             switch(ot) {
3413             case MO_8:
3414                 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
3415                 tcg_gen_ext8u_tl(s->T0, s->T0);
3416                 tcg_gen_ext8u_tl(s->T1, s->T1);
3417                 /* XXX: use 32 bit mul which could be faster */
3418                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3419                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3420                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3421                 tcg_gen_andi_tl(cpu_cc_src, s->T0, 0xff00);
3422                 set_cc_op(s, CC_OP_MULB);
3423                 break;
3424             case MO_16:
3425                 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
3426                 tcg_gen_ext16u_tl(s->T0, s->T0);
3427                 tcg_gen_ext16u_tl(s->T1, s->T1);
3428                 /* XXX: use 32 bit mul which could be faster */
3429                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3430                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3431                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3432                 tcg_gen_shri_tl(s->T0, s->T0, 16);
3433                 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
3434                 tcg_gen_mov_tl(cpu_cc_src, s->T0);
3435                 set_cc_op(s, CC_OP_MULW);
3436                 break;
3437             default:
3438             case MO_32:
3439                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3440                 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
3441                 tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32,
3442                                   s->tmp2_i32, s->tmp3_i32);
3443                 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
3444                 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
3445                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3446                 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
3447                 set_cc_op(s, CC_OP_MULL);
3448                 break;
3449 #ifdef TARGET_X86_64
3450             case MO_64:
3451                 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
3452                                   s->T0, cpu_regs[R_EAX]);
3453                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3454                 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
3455                 set_cc_op(s, CC_OP_MULQ);
3456                 break;
3457 #endif
3458             }
3459             break;
3460         case 5: /* imul */
3461             switch(ot) {
3462             case MO_8:
3463                 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
3464                 tcg_gen_ext8s_tl(s->T0, s->T0);
3465                 tcg_gen_ext8s_tl(s->T1, s->T1);
3466                 /* XXX: use 32 bit mul which could be faster */
3467                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3468                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3469                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3470                 tcg_gen_ext8s_tl(s->tmp0, s->T0);
3471                 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
3472                 set_cc_op(s, CC_OP_MULB);
3473                 break;
3474             case MO_16:
3475                 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
3476                 tcg_gen_ext16s_tl(s->T0, s->T0);
3477                 tcg_gen_ext16s_tl(s->T1, s->T1);
3478                 /* XXX: use 32 bit mul which could be faster */
3479                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3480                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3481                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3482                 tcg_gen_ext16s_tl(s->tmp0, s->T0);
3483                 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
3484                 tcg_gen_shri_tl(s->T0, s->T0, 16);
3485                 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
3486                 set_cc_op(s, CC_OP_MULW);
3487                 break;
3488             default:
3489             case MO_32:
3490                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3491                 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
3492                 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
3493                                   s->tmp2_i32, s->tmp3_i32);
3494                 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
3495                 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
3496                 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
3497                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3498                 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
3499                 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
3500                 set_cc_op(s, CC_OP_MULL);
3501                 break;
3502 #ifdef TARGET_X86_64
3503             case MO_64:
3504                 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
3505                                   s->T0, cpu_regs[R_EAX]);
3506                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3507                 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
3508                 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
3509                 set_cc_op(s, CC_OP_MULQ);
3510                 break;
3511 #endif
3512             }
3513             break;
3514         case 6: /* div */
3515             switch(ot) {
3516             case MO_8:
3517                 gen_helper_divb_AL(tcg_env, s->T0);
3518                 break;
3519             case MO_16:
3520                 gen_helper_divw_AX(tcg_env, s->T0);
3521                 break;
3522             default:
3523             case MO_32:
3524                 gen_helper_divl_EAX(tcg_env, s->T0);
3525                 break;
3526 #ifdef TARGET_X86_64
3527             case MO_64:
3528                 gen_helper_divq_EAX(tcg_env, s->T0);
3529                 break;
3530 #endif
3531             }
3532             break;
3533         case 7: /* idiv */
3534             switch(ot) {
3535             case MO_8:
3536                 gen_helper_idivb_AL(tcg_env, s->T0);
3537                 break;
3538             case MO_16:
3539                 gen_helper_idivw_AX(tcg_env, s->T0);
3540                 break;
3541             default:
3542             case MO_32:
3543                 gen_helper_idivl_EAX(tcg_env, s->T0);
3544                 break;
3545 #ifdef TARGET_X86_64
3546             case MO_64:
3547                 gen_helper_idivq_EAX(tcg_env, s->T0);
3548                 break;
3549 #endif
3550             }
3551             break;
3552         default:
3553             goto unknown_op;
3554         }
3555         break;
3556 
3557     case 0xfe: /* GRP4 */
3558     case 0xff: /* GRP5 */
3559         ot = mo_b_d(b, dflag);
3560 
3561         modrm = x86_ldub_code(env, s);
3562         mod = (modrm >> 6) & 3;
3563         rm = (modrm & 7) | REX_B(s);
3564         op = (modrm >> 3) & 7;
3565         if (op >= 2 && b == 0xfe) {
3566             goto unknown_op;
3567         }
3568         if (CODE64(s)) {
3569             if (op == 2 || op == 4) {
3570                 /* operand size for jumps is 64 bit */
3571                 ot = MO_64;
3572             } else if (op == 3 || op == 5) {
3573                 ot = dflag != MO_16 ? MO_32 + REX_W(s) : MO_16;
3574             } else if (op == 6) {
3575                 /* default push size is 64 bit */
3576                 ot = mo_pushpop(s, dflag);
3577             }
3578         }
3579         if (mod != 3) {
3580             gen_lea_modrm(env, s, modrm);
3581             if (op >= 2 && op != 3 && op != 5)
3582                 gen_op_ld_v(s, ot, s->T0, s->A0);
3583         } else {
3584             gen_op_mov_v_reg(s, ot, s->T0, rm);
3585         }
3586 
3587         switch(op) {
3588         case 0: /* inc Ev */
3589             if (mod != 3)
3590                 opreg = OR_TMP0;
3591             else
3592                 opreg = rm;
3593             gen_inc(s, ot, opreg, 1);
3594             break;
3595         case 1: /* dec Ev */
3596             if (mod != 3)
3597                 opreg = OR_TMP0;
3598             else
3599                 opreg = rm;
3600             gen_inc(s, ot, opreg, -1);
3601             break;
3602         case 2: /* call Ev */
3603             /* XXX: optimize if memory (no 'and' is necessary) */
3604             if (dflag == MO_16) {
3605                 tcg_gen_ext16u_tl(s->T0, s->T0);
3606             }
3607             gen_push_v(s, eip_next_tl(s));
3608             gen_op_jmp_v(s, s->T0);
3609             gen_bnd_jmp(s);
3610             s->base.is_jmp = DISAS_JUMP;
3611             break;
3612         case 3: /* lcall Ev */
3613             if (mod == 3) {
3614                 goto illegal_op;
3615             }
3616             gen_op_ld_v(s, ot, s->T1, s->A0);
3617             gen_add_A0_im(s, 1 << ot);
3618             gen_op_ld_v(s, MO_16, s->T0, s->A0);
3619         do_lcall:
3620             if (PE(s) && !VM86(s)) {
3621                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3622                 gen_helper_lcall_protected(tcg_env, s->tmp2_i32, s->T1,
3623                                            tcg_constant_i32(dflag - 1),
3624                                            eip_next_tl(s));
3625             } else {
3626                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3627                 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
3628                 gen_helper_lcall_real(tcg_env, s->tmp2_i32, s->tmp3_i32,
3629                                       tcg_constant_i32(dflag - 1),
3630                                       eip_next_i32(s));
3631             }
3632             s->base.is_jmp = DISAS_JUMP;
3633             break;
3634         case 4: /* jmp Ev */
3635             if (dflag == MO_16) {
3636                 tcg_gen_ext16u_tl(s->T0, s->T0);
3637             }
3638             gen_op_jmp_v(s, s->T0);
3639             gen_bnd_jmp(s);
3640             s->base.is_jmp = DISAS_JUMP;
3641             break;
3642         case 5: /* ljmp Ev */
3643             if (mod == 3) {
3644                 goto illegal_op;
3645             }
3646             gen_op_ld_v(s, ot, s->T1, s->A0);
3647             gen_add_A0_im(s, 1 << ot);
3648             gen_op_ld_v(s, MO_16, s->T0, s->A0);
3649         do_ljmp:
3650             if (PE(s) && !VM86(s)) {
3651                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3652                 gen_helper_ljmp_protected(tcg_env, s->tmp2_i32, s->T1,
3653                                           eip_next_tl(s));
3654             } else {
3655                 gen_op_movl_seg_T0_vm(s, R_CS);
3656                 gen_op_jmp_v(s, s->T1);
3657             }
3658             s->base.is_jmp = DISAS_JUMP;
3659             break;
3660         case 6: /* push Ev */
3661             gen_push_v(s, s->T0);
3662             break;
3663         default:
3664             goto unknown_op;
3665         }
3666         break;
3667 
3668     case 0x84: /* test Ev, Gv */
3669     case 0x85:
3670         ot = mo_b_d(b, dflag);
3671 
3672         modrm = x86_ldub_code(env, s);
3673         reg = ((modrm >> 3) & 7) | REX_R(s);
3674 
3675         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3676         gen_op_mov_v_reg(s, ot, s->T1, reg);
3677         gen_op_testl_T0_T1_cc(s);
3678         set_cc_op(s, CC_OP_LOGICB + ot);
3679         break;
3680 
3681     case 0xa8: /* test eAX, Iv */
3682     case 0xa9:
3683         ot = mo_b_d(b, dflag);
3684         val = insn_get(env, s, ot);
3685 
3686         gen_op_mov_v_reg(s, ot, s->T0, OR_EAX);
3687         tcg_gen_movi_tl(s->T1, val);
3688         gen_op_testl_T0_T1_cc(s);
3689         set_cc_op(s, CC_OP_LOGICB + ot);
3690         break;
3691 
3692     case 0x98: /* CWDE/CBW */
3693         switch (dflag) {
3694 #ifdef TARGET_X86_64
3695         case MO_64:
3696             gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
3697             tcg_gen_ext32s_tl(s->T0, s->T0);
3698             gen_op_mov_reg_v(s, MO_64, R_EAX, s->T0);
3699             break;
3700 #endif
3701         case MO_32:
3702             gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
3703             tcg_gen_ext16s_tl(s->T0, s->T0);
3704             gen_op_mov_reg_v(s, MO_32, R_EAX, s->T0);
3705             break;
3706         case MO_16:
3707             gen_op_mov_v_reg(s, MO_8, s->T0, R_EAX);
3708             tcg_gen_ext8s_tl(s->T0, s->T0);
3709             gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3710             break;
3711         default:
3712             g_assert_not_reached();
3713         }
3714         break;
3715     case 0x99: /* CDQ/CWD */
3716         switch (dflag) {
3717 #ifdef TARGET_X86_64
3718         case MO_64:
3719             gen_op_mov_v_reg(s, MO_64, s->T0, R_EAX);
3720             tcg_gen_sari_tl(s->T0, s->T0, 63);
3721             gen_op_mov_reg_v(s, MO_64, R_EDX, s->T0);
3722             break;
3723 #endif
3724         case MO_32:
3725             gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
3726             tcg_gen_ext32s_tl(s->T0, s->T0);
3727             tcg_gen_sari_tl(s->T0, s->T0, 31);
3728             gen_op_mov_reg_v(s, MO_32, R_EDX, s->T0);
3729             break;
3730         case MO_16:
3731             gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
3732             tcg_gen_ext16s_tl(s->T0, s->T0);
3733             tcg_gen_sari_tl(s->T0, s->T0, 15);
3734             gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
3735             break;
3736         default:
3737             g_assert_not_reached();
3738         }
3739         break;
3740     case 0x1af: /* imul Gv, Ev */
3741     case 0x69: /* imul Gv, Ev, I */
3742     case 0x6b:
3743         ot = dflag;
3744         modrm = x86_ldub_code(env, s);
3745         reg = ((modrm >> 3) & 7) | REX_R(s);
3746         if (b == 0x69)
3747             s->rip_offset = insn_const_size(ot);
3748         else if (b == 0x6b)
3749             s->rip_offset = 1;
3750         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3751         if (b == 0x69) {
3752             val = insn_get(env, s, ot);
3753             tcg_gen_movi_tl(s->T1, val);
3754         } else if (b == 0x6b) {
3755             val = (int8_t)insn_get(env, s, MO_8);
3756             tcg_gen_movi_tl(s->T1, val);
3757         } else {
3758             gen_op_mov_v_reg(s, ot, s->T1, reg);
3759         }
3760         switch (ot) {
3761 #ifdef TARGET_X86_64
3762         case MO_64:
3763             tcg_gen_muls2_i64(cpu_regs[reg], s->T1, s->T0, s->T1);
3764             tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
3765             tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
3766             tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, s->T1);
3767             break;
3768 #endif
3769         case MO_32:
3770             tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3771             tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
3772             tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
3773                               s->tmp2_i32, s->tmp3_i32);
3774             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
3775             tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
3776             tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
3777             tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
3778             tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
3779             break;
3780         default:
3781             tcg_gen_ext16s_tl(s->T0, s->T0);
3782             tcg_gen_ext16s_tl(s->T1, s->T1);
3783             /* XXX: use 32 bit mul which could be faster */
3784             tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3785             tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3786             tcg_gen_ext16s_tl(s->tmp0, s->T0);
3787             tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
3788             gen_op_mov_reg_v(s, ot, reg, s->T0);
3789             break;
3790         }
3791         set_cc_op(s, CC_OP_MULB + ot);
3792         break;
3793     case 0x1c0:
3794     case 0x1c1: /* xadd Ev, Gv */
3795         ot = mo_b_d(b, dflag);
3796         modrm = x86_ldub_code(env, s);
3797         reg = ((modrm >> 3) & 7) | REX_R(s);
3798         mod = (modrm >> 6) & 3;
3799         gen_op_mov_v_reg(s, ot, s->T0, reg);
3800         if (mod == 3) {
3801             rm = (modrm & 7) | REX_B(s);
3802             gen_op_mov_v_reg(s, ot, s->T1, rm);
3803             tcg_gen_add_tl(s->T0, s->T0, s->T1);
3804             gen_op_mov_reg_v(s, ot, reg, s->T1);
3805             gen_op_mov_reg_v(s, ot, rm, s->T0);
3806         } else {
3807             gen_lea_modrm(env, s, modrm);
3808             if (s->prefix & PREFIX_LOCK) {
3809                 tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0,
3810                                             s->mem_index, ot | MO_LE);
3811                 tcg_gen_add_tl(s->T0, s->T0, s->T1);
3812             } else {
3813                 gen_op_ld_v(s, ot, s->T1, s->A0);
3814                 tcg_gen_add_tl(s->T0, s->T0, s->T1);
3815                 gen_op_st_v(s, ot, s->T0, s->A0);
3816             }
3817             gen_op_mov_reg_v(s, ot, reg, s->T1);
3818         }
3819         gen_op_update2_cc(s);
3820         set_cc_op(s, CC_OP_ADDB + ot);
3821         break;
3822     case 0x1b0:
3823     case 0x1b1: /* cmpxchg Ev, Gv */
3824         {
3825             TCGv oldv, newv, cmpv, dest;
3826 
3827             ot = mo_b_d(b, dflag);
3828             modrm = x86_ldub_code(env, s);
3829             reg = ((modrm >> 3) & 7) | REX_R(s);
3830             mod = (modrm >> 6) & 3;
3831             oldv = tcg_temp_new();
3832             newv = tcg_temp_new();
3833             cmpv = tcg_temp_new();
3834             gen_op_mov_v_reg(s, ot, newv, reg);
3835             tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
3836             gen_extu(ot, cmpv);
3837             if (s->prefix & PREFIX_LOCK) {
3838                 if (mod == 3) {
3839                     goto illegal_op;
3840                 }
3841                 gen_lea_modrm(env, s, modrm);
3842                 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv,
3843                                           s->mem_index, ot | MO_LE);
3844             } else {
3845                 if (mod == 3) {
3846                     rm = (modrm & 7) | REX_B(s);
3847                     gen_op_mov_v_reg(s, ot, oldv, rm);
3848                     gen_extu(ot, oldv);
3849 
3850                     /*
3851                      * Unlike the memory case, where "the destination operand receives
3852                      * a write cycle without regard to the result of the comparison",
3853                      * rm must not be touched altogether if the write fails, including
3854                      * not zero-extending it on 64-bit processors.  So, precompute
3855                      * the result of a successful writeback and perform the movcond
3856                      * directly on cpu_regs.  Also need to write accumulator first, in
3857                      * case rm is part of RAX too.
3858                      */
3859                     dest = gen_op_deposit_reg_v(s, ot, rm, newv, newv);
3860                     tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, newv, dest);
3861                 } else {
3862                     gen_lea_modrm(env, s, modrm);
3863                     gen_op_ld_v(s, ot, oldv, s->A0);
3864 
3865                     /*
3866                      * Perform an unconditional store cycle like physical cpu;
3867                      * must be before changing accumulator to ensure
3868                      * idempotency if the store faults and the instruction
3869                      * is restarted
3870                      */
3871                     tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
3872                     gen_op_st_v(s, ot, newv, s->A0);
3873                 }
3874             }
3875 	    /*
3876 	     * Write EAX only if the cmpxchg fails; reuse newv as the destination,
3877 	     * since it's dead here.
3878 	     */
3879             dest = gen_op_deposit_reg_v(s, ot, R_EAX, newv, oldv);
3880             tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, dest, newv);
3881             tcg_gen_mov_tl(cpu_cc_src, oldv);
3882             tcg_gen_mov_tl(s->cc_srcT, cmpv);
3883             tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
3884             set_cc_op(s, CC_OP_SUBB + ot);
3885         }
3886         break;
3887     case 0x1c7: /* cmpxchg8b */
3888         modrm = x86_ldub_code(env, s);
3889         mod = (modrm >> 6) & 3;
3890         switch ((modrm >> 3) & 7) {
3891         case 1: /* CMPXCHG8, CMPXCHG16 */
3892             if (mod == 3) {
3893                 goto illegal_op;
3894             }
3895 #ifdef TARGET_X86_64
3896             if (dflag == MO_64) {
3897                 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
3898                     goto illegal_op;
3899                 }
3900                 gen_cmpxchg16b(s, env, modrm);
3901                 break;
3902             }
3903 #endif
3904             if (!(s->cpuid_features & CPUID_CX8)) {
3905                 goto illegal_op;
3906             }
3907             gen_cmpxchg8b(s, env, modrm);
3908             break;
3909 
3910         case 7: /* RDSEED, RDPID with f3 prefix */
3911             if (mod != 3 ||
3912                 (s->prefix & (PREFIX_LOCK | PREFIX_REPNZ))) {
3913                 goto illegal_op;
3914             }
3915             if (s->prefix & PREFIX_REPZ) {
3916                 if (!(s->cpuid_ext_features & CPUID_7_0_ECX_RDPID)) {
3917                     goto illegal_op;
3918                 }
3919                 gen_helper_rdpid(s->T0, tcg_env);
3920                 rm = (modrm & 7) | REX_B(s);
3921                 gen_op_mov_reg_v(s, dflag, rm, s->T0);
3922                 break;
3923             } else {
3924                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) {
3925                     goto illegal_op;
3926                 }
3927                 goto do_rdrand;
3928             }
3929 
3930         case 6: /* RDRAND */
3931             if (mod != 3 ||
3932                 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) ||
3933                 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
3934                 goto illegal_op;
3935             }
3936         do_rdrand:
3937             translator_io_start(&s->base);
3938             gen_helper_rdrand(s->T0, tcg_env);
3939             rm = (modrm & 7) | REX_B(s);
3940             gen_op_mov_reg_v(s, dflag, rm, s->T0);
3941             set_cc_op(s, CC_OP_EFLAGS);
3942             break;
3943 
3944         default:
3945             goto illegal_op;
3946         }
3947         break;
3948 
3949         /**************************/
3950         /* push/pop */
3951     case 0x50 ... 0x57: /* push */
3952         gen_op_mov_v_reg(s, MO_32, s->T0, (b & 7) | REX_B(s));
3953         gen_push_v(s, s->T0);
3954         break;
3955     case 0x58 ... 0x5f: /* pop */
3956         ot = gen_pop_T0(s);
3957         /* NOTE: order is important for pop %sp */
3958         gen_pop_update(s, ot);
3959         gen_op_mov_reg_v(s, ot, (b & 7) | REX_B(s), s->T0);
3960         break;
3961     case 0x60: /* pusha */
3962         if (CODE64(s))
3963             goto illegal_op;
3964         gen_pusha(s);
3965         break;
3966     case 0x61: /* popa */
3967         if (CODE64(s))
3968             goto illegal_op;
3969         gen_popa(s);
3970         break;
3971     case 0x68: /* push Iv */
3972     case 0x6a:
3973         ot = mo_pushpop(s, dflag);
3974         if (b == 0x68)
3975             val = insn_get(env, s, ot);
3976         else
3977             val = (int8_t)insn_get(env, s, MO_8);
3978         tcg_gen_movi_tl(s->T0, val);
3979         gen_push_v(s, s->T0);
3980         break;
3981     case 0x8f: /* pop Ev */
3982         modrm = x86_ldub_code(env, s);
3983         mod = (modrm >> 6) & 3;
3984         ot = gen_pop_T0(s);
3985         if (mod == 3) {
3986             /* NOTE: order is important for pop %sp */
3987             gen_pop_update(s, ot);
3988             rm = (modrm & 7) | REX_B(s);
3989             gen_op_mov_reg_v(s, ot, rm, s->T0);
3990         } else {
3991             /* NOTE: order is important too for MMU exceptions */
3992             s->popl_esp_hack = 1 << ot;
3993             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
3994             s->popl_esp_hack = 0;
3995             gen_pop_update(s, ot);
3996         }
3997         break;
3998     case 0xc8: /* enter */
3999         {
4000             int level;
4001             val = x86_lduw_code(env, s);
4002             level = x86_ldub_code(env, s);
4003             gen_enter(s, val, level);
4004         }
4005         break;
4006     case 0xc9: /* leave */
4007         gen_leave(s);
4008         break;
4009     case 0x06: /* push es */
4010     case 0x0e: /* push cs */
4011     case 0x16: /* push ss */
4012     case 0x1e: /* push ds */
4013         if (CODE64(s))
4014             goto illegal_op;
4015         gen_op_movl_T0_seg(s, b >> 3);
4016         gen_push_v(s, s->T0);
4017         break;
4018     case 0x1a0: /* push fs */
4019     case 0x1a8: /* push gs */
4020         gen_op_movl_T0_seg(s, (b >> 3) & 7);
4021         gen_push_v(s, s->T0);
4022         break;
4023     case 0x07: /* pop es */
4024     case 0x17: /* pop ss */
4025     case 0x1f: /* pop ds */
4026         if (CODE64(s))
4027             goto illegal_op;
4028         reg = b >> 3;
4029         ot = gen_pop_T0(s);
4030         gen_movl_seg_T0(s, reg);
4031         gen_pop_update(s, ot);
4032         break;
4033     case 0x1a1: /* pop fs */
4034     case 0x1a9: /* pop gs */
4035         ot = gen_pop_T0(s);
4036         gen_movl_seg_T0(s, (b >> 3) & 7);
4037         gen_pop_update(s, ot);
4038         break;
4039 
4040         /**************************/
4041         /* mov */
4042     case 0x88:
4043     case 0x89: /* mov Gv, Ev */
4044         ot = mo_b_d(b, dflag);
4045         modrm = x86_ldub_code(env, s);
4046         reg = ((modrm >> 3) & 7) | REX_R(s);
4047 
4048         /* generate a generic store */
4049         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
4050         break;
4051     case 0xc6:
4052     case 0xc7: /* mov Ev, Iv */
4053         ot = mo_b_d(b, dflag);
4054         modrm = x86_ldub_code(env, s);
4055         mod = (modrm >> 6) & 3;
4056         if (mod != 3) {
4057             s->rip_offset = insn_const_size(ot);
4058             gen_lea_modrm(env, s, modrm);
4059         }
4060         val = insn_get(env, s, ot);
4061         tcg_gen_movi_tl(s->T0, val);
4062         if (mod != 3) {
4063             gen_op_st_v(s, ot, s->T0, s->A0);
4064         } else {
4065             gen_op_mov_reg_v(s, ot, (modrm & 7) | REX_B(s), s->T0);
4066         }
4067         break;
4068     case 0x8a:
4069     case 0x8b: /* mov Ev, Gv */
4070         ot = mo_b_d(b, dflag);
4071         modrm = x86_ldub_code(env, s);
4072         reg = ((modrm >> 3) & 7) | REX_R(s);
4073 
4074         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4075         gen_op_mov_reg_v(s, ot, reg, s->T0);
4076         break;
4077     case 0x8e: /* mov seg, Gv */
4078         modrm = x86_ldub_code(env, s);
4079         reg = (modrm >> 3) & 7;
4080         if (reg >= 6 || reg == R_CS)
4081             goto illegal_op;
4082         gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
4083         gen_movl_seg_T0(s, reg);
4084         break;
4085     case 0x8c: /* mov Gv, seg */
4086         modrm = x86_ldub_code(env, s);
4087         reg = (modrm >> 3) & 7;
4088         mod = (modrm >> 6) & 3;
4089         if (reg >= 6)
4090             goto illegal_op;
4091         gen_op_movl_T0_seg(s, reg);
4092         ot = mod == 3 ? dflag : MO_16;
4093         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
4094         break;
4095 
4096     case 0x1b6: /* movzbS Gv, Eb */
4097     case 0x1b7: /* movzwS Gv, Eb */
4098     case 0x1be: /* movsbS Gv, Eb */
4099     case 0x1bf: /* movswS Gv, Eb */
4100         {
4101             MemOp d_ot;
4102             MemOp s_ot;
4103 
4104             /* d_ot is the size of destination */
4105             d_ot = dflag;
4106             /* ot is the size of source */
4107             ot = (b & 1) + MO_8;
4108             /* s_ot is the sign+size of source */
4109             s_ot = b & 8 ? MO_SIGN | ot : ot;
4110 
4111             modrm = x86_ldub_code(env, s);
4112             reg = ((modrm >> 3) & 7) | REX_R(s);
4113             mod = (modrm >> 6) & 3;
4114             rm = (modrm & 7) | REX_B(s);
4115 
4116             if (mod == 3) {
4117                 if (s_ot == MO_SB && byte_reg_is_xH(s, rm)) {
4118                     tcg_gen_sextract_tl(s->T0, cpu_regs[rm - 4], 8, 8);
4119                 } else {
4120                     gen_op_mov_v_reg(s, ot, s->T0, rm);
4121                     switch (s_ot) {
4122                     case MO_UB:
4123                         tcg_gen_ext8u_tl(s->T0, s->T0);
4124                         break;
4125                     case MO_SB:
4126                         tcg_gen_ext8s_tl(s->T0, s->T0);
4127                         break;
4128                     case MO_UW:
4129                         tcg_gen_ext16u_tl(s->T0, s->T0);
4130                         break;
4131                     default:
4132                     case MO_SW:
4133                         tcg_gen_ext16s_tl(s->T0, s->T0);
4134                         break;
4135                     }
4136                 }
4137                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
4138             } else {
4139                 gen_lea_modrm(env, s, modrm);
4140                 gen_op_ld_v(s, s_ot, s->T0, s->A0);
4141                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
4142             }
4143         }
4144         break;
4145 
4146     case 0x8d: /* lea */
4147         modrm = x86_ldub_code(env, s);
4148         mod = (modrm >> 6) & 3;
4149         if (mod == 3)
4150             goto illegal_op;
4151         reg = ((modrm >> 3) & 7) | REX_R(s);
4152         {
4153             AddressParts a = gen_lea_modrm_0(env, s, modrm);
4154             TCGv ea = gen_lea_modrm_1(s, a, false);
4155             gen_lea_v_seg(s, s->aflag, ea, -1, -1);
4156             gen_op_mov_reg_v(s, dflag, reg, s->A0);
4157         }
4158         break;
4159 
4160     case 0xa0: /* mov EAX, Ov */
4161     case 0xa1:
4162     case 0xa2: /* mov Ov, EAX */
4163     case 0xa3:
4164         {
4165             target_ulong offset_addr;
4166 
4167             ot = mo_b_d(b, dflag);
4168             offset_addr = insn_get_addr(env, s, s->aflag);
4169             tcg_gen_movi_tl(s->A0, offset_addr);
4170             gen_add_A0_ds_seg(s);
4171             if ((b & 2) == 0) {
4172                 gen_op_ld_v(s, ot, s->T0, s->A0);
4173                 gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
4174             } else {
4175                 gen_op_mov_v_reg(s, ot, s->T0, R_EAX);
4176                 gen_op_st_v(s, ot, s->T0, s->A0);
4177             }
4178         }
4179         break;
4180     case 0xd7: /* xlat */
4181         tcg_gen_mov_tl(s->A0, cpu_regs[R_EBX]);
4182         tcg_gen_ext8u_tl(s->T0, cpu_regs[R_EAX]);
4183         tcg_gen_add_tl(s->A0, s->A0, s->T0);
4184         gen_extu(s->aflag, s->A0);
4185         gen_add_A0_ds_seg(s);
4186         gen_op_ld_v(s, MO_8, s->T0, s->A0);
4187         gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
4188         break;
4189     case 0xb0 ... 0xb7: /* mov R, Ib */
4190         val = insn_get(env, s, MO_8);
4191         tcg_gen_movi_tl(s->T0, val);
4192         gen_op_mov_reg_v(s, MO_8, (b & 7) | REX_B(s), s->T0);
4193         break;
4194     case 0xb8 ... 0xbf: /* mov R, Iv */
4195 #ifdef TARGET_X86_64
4196         if (dflag == MO_64) {
4197             uint64_t tmp;
4198             /* 64 bit case */
4199             tmp = x86_ldq_code(env, s);
4200             reg = (b & 7) | REX_B(s);
4201             tcg_gen_movi_tl(s->T0, tmp);
4202             gen_op_mov_reg_v(s, MO_64, reg, s->T0);
4203         } else
4204 #endif
4205         {
4206             ot = dflag;
4207             val = insn_get(env, s, ot);
4208             reg = (b & 7) | REX_B(s);
4209             tcg_gen_movi_tl(s->T0, val);
4210             gen_op_mov_reg_v(s, ot, reg, s->T0);
4211         }
4212         break;
4213 
4214     case 0x91 ... 0x97: /* xchg R, EAX */
4215     do_xchg_reg_eax:
4216         ot = dflag;
4217         reg = (b & 7) | REX_B(s);
4218         rm = R_EAX;
4219         goto do_xchg_reg;
4220     case 0x86:
4221     case 0x87: /* xchg Ev, Gv */
4222         ot = mo_b_d(b, dflag);
4223         modrm = x86_ldub_code(env, s);
4224         reg = ((modrm >> 3) & 7) | REX_R(s);
4225         mod = (modrm >> 6) & 3;
4226         if (mod == 3) {
4227             rm = (modrm & 7) | REX_B(s);
4228         do_xchg_reg:
4229             gen_op_mov_v_reg(s, ot, s->T0, reg);
4230             gen_op_mov_v_reg(s, ot, s->T1, rm);
4231             gen_op_mov_reg_v(s, ot, rm, s->T0);
4232             gen_op_mov_reg_v(s, ot, reg, s->T1);
4233         } else {
4234             gen_lea_modrm(env, s, modrm);
4235             gen_op_mov_v_reg(s, ot, s->T0, reg);
4236             /* for xchg, lock is implicit */
4237             tcg_gen_atomic_xchg_tl(s->T1, s->A0, s->T0,
4238                                    s->mem_index, ot | MO_LE);
4239             gen_op_mov_reg_v(s, ot, reg, s->T1);
4240         }
4241         break;
4242     case 0xc4: /* les Gv */
4243         /* In CODE64 this is VEX3; see above.  */
4244         op = R_ES;
4245         goto do_lxx;
4246     case 0xc5: /* lds Gv */
4247         /* In CODE64 this is VEX2; see above.  */
4248         op = R_DS;
4249         goto do_lxx;
4250     case 0x1b2: /* lss Gv */
4251         op = R_SS;
4252         goto do_lxx;
4253     case 0x1b4: /* lfs Gv */
4254         op = R_FS;
4255         goto do_lxx;
4256     case 0x1b5: /* lgs Gv */
4257         op = R_GS;
4258     do_lxx:
4259         ot = dflag != MO_16 ? MO_32 : MO_16;
4260         modrm = x86_ldub_code(env, s);
4261         reg = ((modrm >> 3) & 7) | REX_R(s);
4262         mod = (modrm >> 6) & 3;
4263         if (mod == 3)
4264             goto illegal_op;
4265         gen_lea_modrm(env, s, modrm);
4266         gen_op_ld_v(s, ot, s->T1, s->A0);
4267         gen_add_A0_im(s, 1 << ot);
4268         /* load the segment first to handle exceptions properly */
4269         gen_op_ld_v(s, MO_16, s->T0, s->A0);
4270         gen_movl_seg_T0(s, op);
4271         /* then put the data */
4272         gen_op_mov_reg_v(s, ot, reg, s->T1);
4273         break;
4274 
4275         /************************/
4276         /* shifts */
4277     case 0xc0:
4278     case 0xc1:
4279         /* shift Ev,Ib */
4280         shift = 2;
4281     grp2:
4282         {
4283             ot = mo_b_d(b, dflag);
4284             modrm = x86_ldub_code(env, s);
4285             mod = (modrm >> 6) & 3;
4286             op = (modrm >> 3) & 7;
4287 
4288             if (mod != 3) {
4289                 if (shift == 2) {
4290                     s->rip_offset = 1;
4291                 }
4292                 gen_lea_modrm(env, s, modrm);
4293                 opreg = OR_TMP0;
4294             } else {
4295                 opreg = (modrm & 7) | REX_B(s);
4296             }
4297 
4298             /* simpler op */
4299             if (shift == 0) {
4300                 gen_shift(s, op, ot, opreg, OR_ECX);
4301             } else {
4302                 if (shift == 2) {
4303                     shift = x86_ldub_code(env, s);
4304                 }
4305                 gen_shifti(s, op, ot, opreg, shift);
4306             }
4307         }
4308         break;
4309     case 0xd0:
4310     case 0xd1:
4311         /* shift Ev,1 */
4312         shift = 1;
4313         goto grp2;
4314     case 0xd2:
4315     case 0xd3:
4316         /* shift Ev,cl */
4317         shift = 0;
4318         goto grp2;
4319 
4320     case 0x1a4: /* shld imm */
4321         op = 0;
4322         shift = 1;
4323         goto do_shiftd;
4324     case 0x1a5: /* shld cl */
4325         op = 0;
4326         shift = 0;
4327         goto do_shiftd;
4328     case 0x1ac: /* shrd imm */
4329         op = 1;
4330         shift = 1;
4331         goto do_shiftd;
4332     case 0x1ad: /* shrd cl */
4333         op = 1;
4334         shift = 0;
4335     do_shiftd:
4336         ot = dflag;
4337         modrm = x86_ldub_code(env, s);
4338         mod = (modrm >> 6) & 3;
4339         rm = (modrm & 7) | REX_B(s);
4340         reg = ((modrm >> 3) & 7) | REX_R(s);
4341         if (mod != 3) {
4342             gen_lea_modrm(env, s, modrm);
4343             opreg = OR_TMP0;
4344         } else {
4345             opreg = rm;
4346         }
4347         gen_op_mov_v_reg(s, ot, s->T1, reg);
4348 
4349         if (shift) {
4350             TCGv imm = tcg_constant_tl(x86_ldub_code(env, s));
4351             gen_shiftd_rm_T1(s, ot, opreg, op, imm);
4352         } else {
4353             gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
4354         }
4355         break;
4356 
4357         /************************/
4358         /* floats */
4359     case 0xd8 ... 0xdf:
4360         {
4361             bool update_fip = true;
4362 
4363             if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4364                 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4365                 /* XXX: what to do if illegal op ? */
4366                 gen_exception(s, EXCP07_PREX);
4367                 break;
4368             }
4369             modrm = x86_ldub_code(env, s);
4370             mod = (modrm >> 6) & 3;
4371             rm = modrm & 7;
4372             op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4373             if (mod != 3) {
4374                 /* memory op */
4375                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
4376                 TCGv ea = gen_lea_modrm_1(s, a, false);
4377                 TCGv last_addr = tcg_temp_new();
4378                 bool update_fdp = true;
4379 
4380                 tcg_gen_mov_tl(last_addr, ea);
4381                 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
4382 
4383                 switch (op) {
4384                 case 0x00 ... 0x07: /* fxxxs */
4385                 case 0x10 ... 0x17: /* fixxxl */
4386                 case 0x20 ... 0x27: /* fxxxl */
4387                 case 0x30 ... 0x37: /* fixxx */
4388                     {
4389                         int op1;
4390                         op1 = op & 7;
4391 
4392                         switch (op >> 4) {
4393                         case 0:
4394                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4395                                                 s->mem_index, MO_LEUL);
4396                             gen_helper_flds_FT0(tcg_env, s->tmp2_i32);
4397                             break;
4398                         case 1:
4399                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4400                                                 s->mem_index, MO_LEUL);
4401                             gen_helper_fildl_FT0(tcg_env, s->tmp2_i32);
4402                             break;
4403                         case 2:
4404                             tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4405                                                 s->mem_index, MO_LEUQ);
4406                             gen_helper_fldl_FT0(tcg_env, s->tmp1_i64);
4407                             break;
4408                         case 3:
4409                         default:
4410                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4411                                                 s->mem_index, MO_LESW);
4412                             gen_helper_fildl_FT0(tcg_env, s->tmp2_i32);
4413                             break;
4414                         }
4415 
4416                         gen_helper_fp_arith_ST0_FT0(op1);
4417                         if (op1 == 3) {
4418                             /* fcomp needs pop */
4419                             gen_helper_fpop(tcg_env);
4420                         }
4421                     }
4422                     break;
4423                 case 0x08: /* flds */
4424                 case 0x0a: /* fsts */
4425                 case 0x0b: /* fstps */
4426                 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
4427                 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
4428                 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
4429                     switch (op & 7) {
4430                     case 0:
4431                         switch (op >> 4) {
4432                         case 0:
4433                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4434                                                 s->mem_index, MO_LEUL);
4435                             gen_helper_flds_ST0(tcg_env, s->tmp2_i32);
4436                             break;
4437                         case 1:
4438                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4439                                                 s->mem_index, MO_LEUL);
4440                             gen_helper_fildl_ST0(tcg_env, s->tmp2_i32);
4441                             break;
4442                         case 2:
4443                             tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4444                                                 s->mem_index, MO_LEUQ);
4445                             gen_helper_fldl_ST0(tcg_env, s->tmp1_i64);
4446                             break;
4447                         case 3:
4448                         default:
4449                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4450                                                 s->mem_index, MO_LESW);
4451                             gen_helper_fildl_ST0(tcg_env, s->tmp2_i32);
4452                             break;
4453                         }
4454                         break;
4455                     case 1:
4456                         /* XXX: the corresponding CPUID bit must be tested ! */
4457                         switch (op >> 4) {
4458                         case 1:
4459                             gen_helper_fisttl_ST0(s->tmp2_i32, tcg_env);
4460                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4461                                                 s->mem_index, MO_LEUL);
4462                             break;
4463                         case 2:
4464                             gen_helper_fisttll_ST0(s->tmp1_i64, tcg_env);
4465                             tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4466                                                 s->mem_index, MO_LEUQ);
4467                             break;
4468                         case 3:
4469                         default:
4470                             gen_helper_fistt_ST0(s->tmp2_i32, tcg_env);
4471                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4472                                                 s->mem_index, MO_LEUW);
4473                             break;
4474                         }
4475                         gen_helper_fpop(tcg_env);
4476                         break;
4477                     default:
4478                         switch (op >> 4) {
4479                         case 0:
4480                             gen_helper_fsts_ST0(s->tmp2_i32, tcg_env);
4481                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4482                                                 s->mem_index, MO_LEUL);
4483                             break;
4484                         case 1:
4485                             gen_helper_fistl_ST0(s->tmp2_i32, tcg_env);
4486                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4487                                                 s->mem_index, MO_LEUL);
4488                             break;
4489                         case 2:
4490                             gen_helper_fstl_ST0(s->tmp1_i64, tcg_env);
4491                             tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4492                                                 s->mem_index, MO_LEUQ);
4493                             break;
4494                         case 3:
4495                         default:
4496                             gen_helper_fist_ST0(s->tmp2_i32, tcg_env);
4497                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4498                                                 s->mem_index, MO_LEUW);
4499                             break;
4500                         }
4501                         if ((op & 7) == 3) {
4502                             gen_helper_fpop(tcg_env);
4503                         }
4504                         break;
4505                     }
4506                     break;
4507                 case 0x0c: /* fldenv mem */
4508                     gen_helper_fldenv(tcg_env, s->A0,
4509                                       tcg_constant_i32(dflag - 1));
4510                     update_fip = update_fdp = false;
4511                     break;
4512                 case 0x0d: /* fldcw mem */
4513                     tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4514                                         s->mem_index, MO_LEUW);
4515                     gen_helper_fldcw(tcg_env, s->tmp2_i32);
4516                     update_fip = update_fdp = false;
4517                     break;
4518                 case 0x0e: /* fnstenv mem */
4519                     gen_helper_fstenv(tcg_env, s->A0,
4520                                       tcg_constant_i32(dflag - 1));
4521                     update_fip = update_fdp = false;
4522                     break;
4523                 case 0x0f: /* fnstcw mem */
4524                     gen_helper_fnstcw(s->tmp2_i32, tcg_env);
4525                     tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4526                                         s->mem_index, MO_LEUW);
4527                     update_fip = update_fdp = false;
4528                     break;
4529                 case 0x1d: /* fldt mem */
4530                     gen_helper_fldt_ST0(tcg_env, s->A0);
4531                     break;
4532                 case 0x1f: /* fstpt mem */
4533                     gen_helper_fstt_ST0(tcg_env, s->A0);
4534                     gen_helper_fpop(tcg_env);
4535                     break;
4536                 case 0x2c: /* frstor mem */
4537                     gen_helper_frstor(tcg_env, s->A0,
4538                                       tcg_constant_i32(dflag - 1));
4539                     update_fip = update_fdp = false;
4540                     break;
4541                 case 0x2e: /* fnsave mem */
4542                     gen_helper_fsave(tcg_env, s->A0,
4543                                      tcg_constant_i32(dflag - 1));
4544                     update_fip = update_fdp = false;
4545                     break;
4546                 case 0x2f: /* fnstsw mem */
4547                     gen_helper_fnstsw(s->tmp2_i32, tcg_env);
4548                     tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4549                                         s->mem_index, MO_LEUW);
4550                     update_fip = update_fdp = false;
4551                     break;
4552                 case 0x3c: /* fbld */
4553                     gen_helper_fbld_ST0(tcg_env, s->A0);
4554                     break;
4555                 case 0x3e: /* fbstp */
4556                     gen_helper_fbst_ST0(tcg_env, s->A0);
4557                     gen_helper_fpop(tcg_env);
4558                     break;
4559                 case 0x3d: /* fildll */
4560                     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4561                                         s->mem_index, MO_LEUQ);
4562                     gen_helper_fildll_ST0(tcg_env, s->tmp1_i64);
4563                     break;
4564                 case 0x3f: /* fistpll */
4565                     gen_helper_fistll_ST0(s->tmp1_i64, tcg_env);
4566                     tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4567                                         s->mem_index, MO_LEUQ);
4568                     gen_helper_fpop(tcg_env);
4569                     break;
4570                 default:
4571                     goto unknown_op;
4572                 }
4573 
4574                 if (update_fdp) {
4575                     int last_seg = s->override >= 0 ? s->override : a.def_seg;
4576 
4577                     tcg_gen_ld_i32(s->tmp2_i32, tcg_env,
4578                                    offsetof(CPUX86State,
4579                                             segs[last_seg].selector));
4580                     tcg_gen_st16_i32(s->tmp2_i32, tcg_env,
4581                                      offsetof(CPUX86State, fpds));
4582                     tcg_gen_st_tl(last_addr, tcg_env,
4583                                   offsetof(CPUX86State, fpdp));
4584                 }
4585             } else {
4586                 /* register float ops */
4587                 opreg = rm;
4588 
4589                 switch (op) {
4590                 case 0x08: /* fld sti */
4591                     gen_helper_fpush(tcg_env);
4592                     gen_helper_fmov_ST0_STN(tcg_env,
4593                                             tcg_constant_i32((opreg + 1) & 7));
4594                     break;
4595                 case 0x09: /* fxchg sti */
4596                 case 0x29: /* fxchg4 sti, undocumented op */
4597                 case 0x39: /* fxchg7 sti, undocumented op */
4598                     gen_helper_fxchg_ST0_STN(tcg_env, tcg_constant_i32(opreg));
4599                     break;
4600                 case 0x0a: /* grp d9/2 */
4601                     switch (rm) {
4602                     case 0: /* fnop */
4603                         /*
4604                          * check exceptions (FreeBSD FPU probe)
4605                          * needs to be treated as I/O because of ferr_irq
4606                          */
4607                         translator_io_start(&s->base);
4608                         gen_helper_fwait(tcg_env);
4609                         update_fip = false;
4610                         break;
4611                     default:
4612                         goto unknown_op;
4613                     }
4614                     break;
4615                 case 0x0c: /* grp d9/4 */
4616                     switch (rm) {
4617                     case 0: /* fchs */
4618                         gen_helper_fchs_ST0(tcg_env);
4619                         break;
4620                     case 1: /* fabs */
4621                         gen_helper_fabs_ST0(tcg_env);
4622                         break;
4623                     case 4: /* ftst */
4624                         gen_helper_fldz_FT0(tcg_env);
4625                         gen_helper_fcom_ST0_FT0(tcg_env);
4626                         break;
4627                     case 5: /* fxam */
4628                         gen_helper_fxam_ST0(tcg_env);
4629                         break;
4630                     default:
4631                         goto unknown_op;
4632                     }
4633                     break;
4634                 case 0x0d: /* grp d9/5 */
4635                     {
4636                         switch (rm) {
4637                         case 0:
4638                             gen_helper_fpush(tcg_env);
4639                             gen_helper_fld1_ST0(tcg_env);
4640                             break;
4641                         case 1:
4642                             gen_helper_fpush(tcg_env);
4643                             gen_helper_fldl2t_ST0(tcg_env);
4644                             break;
4645                         case 2:
4646                             gen_helper_fpush(tcg_env);
4647                             gen_helper_fldl2e_ST0(tcg_env);
4648                             break;
4649                         case 3:
4650                             gen_helper_fpush(tcg_env);
4651                             gen_helper_fldpi_ST0(tcg_env);
4652                             break;
4653                         case 4:
4654                             gen_helper_fpush(tcg_env);
4655                             gen_helper_fldlg2_ST0(tcg_env);
4656                             break;
4657                         case 5:
4658                             gen_helper_fpush(tcg_env);
4659                             gen_helper_fldln2_ST0(tcg_env);
4660                             break;
4661                         case 6:
4662                             gen_helper_fpush(tcg_env);
4663                             gen_helper_fldz_ST0(tcg_env);
4664                             break;
4665                         default:
4666                             goto unknown_op;
4667                         }
4668                     }
4669                     break;
4670                 case 0x0e: /* grp d9/6 */
4671                     switch (rm) {
4672                     case 0: /* f2xm1 */
4673                         gen_helper_f2xm1(tcg_env);
4674                         break;
4675                     case 1: /* fyl2x */
4676                         gen_helper_fyl2x(tcg_env);
4677                         break;
4678                     case 2: /* fptan */
4679                         gen_helper_fptan(tcg_env);
4680                         break;
4681                     case 3: /* fpatan */
4682                         gen_helper_fpatan(tcg_env);
4683                         break;
4684                     case 4: /* fxtract */
4685                         gen_helper_fxtract(tcg_env);
4686                         break;
4687                     case 5: /* fprem1 */
4688                         gen_helper_fprem1(tcg_env);
4689                         break;
4690                     case 6: /* fdecstp */
4691                         gen_helper_fdecstp(tcg_env);
4692                         break;
4693                     default:
4694                     case 7: /* fincstp */
4695                         gen_helper_fincstp(tcg_env);
4696                         break;
4697                     }
4698                     break;
4699                 case 0x0f: /* grp d9/7 */
4700                     switch (rm) {
4701                     case 0: /* fprem */
4702                         gen_helper_fprem(tcg_env);
4703                         break;
4704                     case 1: /* fyl2xp1 */
4705                         gen_helper_fyl2xp1(tcg_env);
4706                         break;
4707                     case 2: /* fsqrt */
4708                         gen_helper_fsqrt(tcg_env);
4709                         break;
4710                     case 3: /* fsincos */
4711                         gen_helper_fsincos(tcg_env);
4712                         break;
4713                     case 5: /* fscale */
4714                         gen_helper_fscale(tcg_env);
4715                         break;
4716                     case 4: /* frndint */
4717                         gen_helper_frndint(tcg_env);
4718                         break;
4719                     case 6: /* fsin */
4720                         gen_helper_fsin(tcg_env);
4721                         break;
4722                     default:
4723                     case 7: /* fcos */
4724                         gen_helper_fcos(tcg_env);
4725                         break;
4726                     }
4727                     break;
4728                 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
4729                 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
4730                 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
4731                     {
4732                         int op1;
4733 
4734                         op1 = op & 7;
4735                         if (op >= 0x20) {
4736                             gen_helper_fp_arith_STN_ST0(op1, opreg);
4737                             if (op >= 0x30) {
4738                                 gen_helper_fpop(tcg_env);
4739                             }
4740                         } else {
4741                             gen_helper_fmov_FT0_STN(tcg_env,
4742                                                     tcg_constant_i32(opreg));
4743                             gen_helper_fp_arith_ST0_FT0(op1);
4744                         }
4745                     }
4746                     break;
4747                 case 0x02: /* fcom */
4748                 case 0x22: /* fcom2, undocumented op */
4749                     gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4750                     gen_helper_fcom_ST0_FT0(tcg_env);
4751                     break;
4752                 case 0x03: /* fcomp */
4753                 case 0x23: /* fcomp3, undocumented op */
4754                 case 0x32: /* fcomp5, undocumented op */
4755                     gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4756                     gen_helper_fcom_ST0_FT0(tcg_env);
4757                     gen_helper_fpop(tcg_env);
4758                     break;
4759                 case 0x15: /* da/5 */
4760                     switch (rm) {
4761                     case 1: /* fucompp */
4762                         gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1));
4763                         gen_helper_fucom_ST0_FT0(tcg_env);
4764                         gen_helper_fpop(tcg_env);
4765                         gen_helper_fpop(tcg_env);
4766                         break;
4767                     default:
4768                         goto unknown_op;
4769                     }
4770                     break;
4771                 case 0x1c:
4772                     switch (rm) {
4773                     case 0: /* feni (287 only, just do nop here) */
4774                         break;
4775                     case 1: /* fdisi (287 only, just do nop here) */
4776                         break;
4777                     case 2: /* fclex */
4778                         gen_helper_fclex(tcg_env);
4779                         update_fip = false;
4780                         break;
4781                     case 3: /* fninit */
4782                         gen_helper_fninit(tcg_env);
4783                         update_fip = false;
4784                         break;
4785                     case 4: /* fsetpm (287 only, just do nop here) */
4786                         break;
4787                     default:
4788                         goto unknown_op;
4789                     }
4790                     break;
4791                 case 0x1d: /* fucomi */
4792                     if (!(s->cpuid_features & CPUID_CMOV)) {
4793                         goto illegal_op;
4794                     }
4795                     gen_update_cc_op(s);
4796                     gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4797                     gen_helper_fucomi_ST0_FT0(tcg_env);
4798                     set_cc_op(s, CC_OP_EFLAGS);
4799                     break;
4800                 case 0x1e: /* fcomi */
4801                     if (!(s->cpuid_features & CPUID_CMOV)) {
4802                         goto illegal_op;
4803                     }
4804                     gen_update_cc_op(s);
4805                     gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4806                     gen_helper_fcomi_ST0_FT0(tcg_env);
4807                     set_cc_op(s, CC_OP_EFLAGS);
4808                     break;
4809                 case 0x28: /* ffree sti */
4810                     gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg));
4811                     break;
4812                 case 0x2a: /* fst sti */
4813                     gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg));
4814                     break;
4815                 case 0x2b: /* fstp sti */
4816                 case 0x0b: /* fstp1 sti, undocumented op */
4817                 case 0x3a: /* fstp8 sti, undocumented op */
4818                 case 0x3b: /* fstp9 sti, undocumented op */
4819                     gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg));
4820                     gen_helper_fpop(tcg_env);
4821                     break;
4822                 case 0x2c: /* fucom st(i) */
4823                     gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4824                     gen_helper_fucom_ST0_FT0(tcg_env);
4825                     break;
4826                 case 0x2d: /* fucomp st(i) */
4827                     gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4828                     gen_helper_fucom_ST0_FT0(tcg_env);
4829                     gen_helper_fpop(tcg_env);
4830                     break;
4831                 case 0x33: /* de/3 */
4832                     switch (rm) {
4833                     case 1: /* fcompp */
4834                         gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1));
4835                         gen_helper_fcom_ST0_FT0(tcg_env);
4836                         gen_helper_fpop(tcg_env);
4837                         gen_helper_fpop(tcg_env);
4838                         break;
4839                     default:
4840                         goto unknown_op;
4841                     }
4842                     break;
4843                 case 0x38: /* ffreep sti, undocumented op */
4844                     gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg));
4845                     gen_helper_fpop(tcg_env);
4846                     break;
4847                 case 0x3c: /* df/4 */
4848                     switch (rm) {
4849                     case 0:
4850                         gen_helper_fnstsw(s->tmp2_i32, tcg_env);
4851                         tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
4852                         gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
4853                         break;
4854                     default:
4855                         goto unknown_op;
4856                     }
4857                     break;
4858                 case 0x3d: /* fucomip */
4859                     if (!(s->cpuid_features & CPUID_CMOV)) {
4860                         goto illegal_op;
4861                     }
4862                     gen_update_cc_op(s);
4863                     gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4864                     gen_helper_fucomi_ST0_FT0(tcg_env);
4865                     gen_helper_fpop(tcg_env);
4866                     set_cc_op(s, CC_OP_EFLAGS);
4867                     break;
4868                 case 0x3e: /* fcomip */
4869                     if (!(s->cpuid_features & CPUID_CMOV)) {
4870                         goto illegal_op;
4871                     }
4872                     gen_update_cc_op(s);
4873                     gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4874                     gen_helper_fcomi_ST0_FT0(tcg_env);
4875                     gen_helper_fpop(tcg_env);
4876                     set_cc_op(s, CC_OP_EFLAGS);
4877                     break;
4878                 case 0x10 ... 0x13: /* fcmovxx */
4879                 case 0x18 ... 0x1b:
4880                     {
4881                         int op1;
4882                         TCGLabel *l1;
4883                         static const uint8_t fcmov_cc[8] = {
4884                             (JCC_B << 1),
4885                             (JCC_Z << 1),
4886                             (JCC_BE << 1),
4887                             (JCC_P << 1),
4888                         };
4889 
4890                         if (!(s->cpuid_features & CPUID_CMOV)) {
4891                             goto illegal_op;
4892                         }
4893                         op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
4894                         l1 = gen_new_label();
4895                         gen_jcc1_noeob(s, op1, l1);
4896                         gen_helper_fmov_ST0_STN(tcg_env,
4897                                                 tcg_constant_i32(opreg));
4898                         gen_set_label(l1);
4899                     }
4900                     break;
4901                 default:
4902                     goto unknown_op;
4903                 }
4904             }
4905 
4906             if (update_fip) {
4907                 tcg_gen_ld_i32(s->tmp2_i32, tcg_env,
4908                                offsetof(CPUX86State, segs[R_CS].selector));
4909                 tcg_gen_st16_i32(s->tmp2_i32, tcg_env,
4910                                  offsetof(CPUX86State, fpcs));
4911                 tcg_gen_st_tl(eip_cur_tl(s),
4912                               tcg_env, offsetof(CPUX86State, fpip));
4913             }
4914         }
4915         break;
4916         /************************/
4917         /* string ops */
4918 
4919     case 0xa4: /* movsS */
4920     case 0xa5:
4921         ot = mo_b_d(b, dflag);
4922         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4923             gen_repz_movs(s, ot);
4924         } else {
4925             gen_movs(s, ot);
4926         }
4927         break;
4928 
4929     case 0xaa: /* stosS */
4930     case 0xab:
4931         ot = mo_b_d(b, dflag);
4932         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4933             gen_repz_stos(s, ot);
4934         } else {
4935             gen_stos(s, ot);
4936         }
4937         break;
4938     case 0xac: /* lodsS */
4939     case 0xad:
4940         ot = mo_b_d(b, dflag);
4941         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4942             gen_repz_lods(s, ot);
4943         } else {
4944             gen_lods(s, ot);
4945         }
4946         break;
4947     case 0xae: /* scasS */
4948     case 0xaf:
4949         ot = mo_b_d(b, dflag);
4950         if (prefixes & PREFIX_REPNZ) {
4951             gen_repz_scas(s, ot, 1);
4952         } else if (prefixes & PREFIX_REPZ) {
4953             gen_repz_scas(s, ot, 0);
4954         } else {
4955             gen_scas(s, ot);
4956         }
4957         break;
4958 
4959     case 0xa6: /* cmpsS */
4960     case 0xa7:
4961         ot = mo_b_d(b, dflag);
4962         if (prefixes & PREFIX_REPNZ) {
4963             gen_repz_cmps(s, ot, 1);
4964         } else if (prefixes & PREFIX_REPZ) {
4965             gen_repz_cmps(s, ot, 0);
4966         } else {
4967             gen_cmps(s, ot);
4968         }
4969         break;
4970     case 0x6c: /* insS */
4971     case 0x6d:
4972         ot = mo_b_d32(b, dflag);
4973         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
4974         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
4975         if (!gen_check_io(s, ot, s->tmp2_i32,
4976                           SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
4977             break;
4978         }
4979         translator_io_start(&s->base);
4980         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4981             gen_repz_ins(s, ot);
4982         } else {
4983             gen_ins(s, ot);
4984         }
4985         break;
4986     case 0x6e: /* outsS */
4987     case 0x6f:
4988         ot = mo_b_d32(b, dflag);
4989         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
4990         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
4991         if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) {
4992             break;
4993         }
4994         translator_io_start(&s->base);
4995         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4996             gen_repz_outs(s, ot);
4997         } else {
4998             gen_outs(s, ot);
4999         }
5000         break;
5001 
5002         /************************/
5003         /* port I/O */
5004 
5005     case 0xe4:
5006     case 0xe5:
5007         ot = mo_b_d32(b, dflag);
5008         val = x86_ldub_code(env, s);
5009         tcg_gen_movi_i32(s->tmp2_i32, val);
5010         if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
5011             break;
5012         }
5013         translator_io_start(&s->base);
5014         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
5015         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
5016         gen_bpt_io(s, s->tmp2_i32, ot);
5017         break;
5018     case 0xe6:
5019     case 0xe7:
5020         ot = mo_b_d32(b, dflag);
5021         val = x86_ldub_code(env, s);
5022         tcg_gen_movi_i32(s->tmp2_i32, val);
5023         if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
5024             break;
5025         }
5026         translator_io_start(&s->base);
5027         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
5028         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5029         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
5030         gen_bpt_io(s, s->tmp2_i32, ot);
5031         break;
5032     case 0xec:
5033     case 0xed:
5034         ot = mo_b_d32(b, dflag);
5035         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
5036         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
5037         if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
5038             break;
5039         }
5040         translator_io_start(&s->base);
5041         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
5042         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
5043         gen_bpt_io(s, s->tmp2_i32, ot);
5044         break;
5045     case 0xee:
5046     case 0xef:
5047         ot = mo_b_d32(b, dflag);
5048         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
5049         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
5050         if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
5051             break;
5052         }
5053         translator_io_start(&s->base);
5054         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
5055         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5056         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
5057         gen_bpt_io(s, s->tmp2_i32, ot);
5058         break;
5059 
5060         /************************/
5061         /* control */
5062     case 0xc2: /* ret im */
5063         val = x86_ldsw_code(env, s);
5064         ot = gen_pop_T0(s);
5065         gen_stack_update(s, val + (1 << ot));
5066         /* Note that gen_pop_T0 uses a zero-extending load.  */
5067         gen_op_jmp_v(s, s->T0);
5068         gen_bnd_jmp(s);
5069         s->base.is_jmp = DISAS_JUMP;
5070         break;
5071     case 0xc3: /* ret */
5072         ot = gen_pop_T0(s);
5073         gen_pop_update(s, ot);
5074         /* Note that gen_pop_T0 uses a zero-extending load.  */
5075         gen_op_jmp_v(s, s->T0);
5076         gen_bnd_jmp(s);
5077         s->base.is_jmp = DISAS_JUMP;
5078         break;
5079     case 0xca: /* lret im */
5080         val = x86_ldsw_code(env, s);
5081     do_lret:
5082         if (PE(s) && !VM86(s)) {
5083             gen_update_cc_op(s);
5084             gen_update_eip_cur(s);
5085             gen_helper_lret_protected(tcg_env, tcg_constant_i32(dflag - 1),
5086                                       tcg_constant_i32(val));
5087         } else {
5088             gen_stack_A0(s);
5089             /* pop offset */
5090             gen_op_ld_v(s, dflag, s->T0, s->A0);
5091             /* NOTE: keeping EIP updated is not a problem in case of
5092                exception */
5093             gen_op_jmp_v(s, s->T0);
5094             /* pop selector */
5095             gen_add_A0_im(s, 1 << dflag);
5096             gen_op_ld_v(s, dflag, s->T0, s->A0);
5097             gen_op_movl_seg_T0_vm(s, R_CS);
5098             /* add stack offset */
5099             gen_stack_update(s, val + (2 << dflag));
5100         }
5101         s->base.is_jmp = DISAS_EOB_ONLY;
5102         break;
5103     case 0xcb: /* lret */
5104         val = 0;
5105         goto do_lret;
5106     case 0xcf: /* iret */
5107         gen_svm_check_intercept(s, SVM_EXIT_IRET);
5108         if (!PE(s) || VM86(s)) {
5109             /* real mode or vm86 mode */
5110             if (!check_vm86_iopl(s)) {
5111                 break;
5112             }
5113             gen_helper_iret_real(tcg_env, tcg_constant_i32(dflag - 1));
5114         } else {
5115             gen_helper_iret_protected(tcg_env, tcg_constant_i32(dflag - 1),
5116                                       eip_next_i32(s));
5117         }
5118         set_cc_op(s, CC_OP_EFLAGS);
5119         s->base.is_jmp = DISAS_EOB_ONLY;
5120         break;
5121     case 0xe8: /* call im */
5122         {
5123             int diff = (dflag != MO_16
5124                         ? (int32_t)insn_get(env, s, MO_32)
5125                         : (int16_t)insn_get(env, s, MO_16));
5126             gen_push_v(s, eip_next_tl(s));
5127             gen_bnd_jmp(s);
5128             gen_jmp_rel(s, dflag, diff, 0);
5129         }
5130         break;
5131     case 0x9a: /* lcall im */
5132         {
5133             unsigned int selector, offset;
5134 
5135             if (CODE64(s))
5136                 goto illegal_op;
5137             ot = dflag;
5138             offset = insn_get(env, s, ot);
5139             selector = insn_get(env, s, MO_16);
5140 
5141             tcg_gen_movi_tl(s->T0, selector);
5142             tcg_gen_movi_tl(s->T1, offset);
5143         }
5144         goto do_lcall;
5145     case 0xe9: /* jmp im */
5146         {
5147             int diff = (dflag != MO_16
5148                         ? (int32_t)insn_get(env, s, MO_32)
5149                         : (int16_t)insn_get(env, s, MO_16));
5150             gen_bnd_jmp(s);
5151             gen_jmp_rel(s, dflag, diff, 0);
5152         }
5153         break;
5154     case 0xea: /* ljmp im */
5155         {
5156             unsigned int selector, offset;
5157 
5158             if (CODE64(s))
5159                 goto illegal_op;
5160             ot = dflag;
5161             offset = insn_get(env, s, ot);
5162             selector = insn_get(env, s, MO_16);
5163 
5164             tcg_gen_movi_tl(s->T0, selector);
5165             tcg_gen_movi_tl(s->T1, offset);
5166         }
5167         goto do_ljmp;
5168     case 0xeb: /* jmp Jb */
5169         {
5170             int diff = (int8_t)insn_get(env, s, MO_8);
5171             gen_jmp_rel(s, dflag, diff, 0);
5172         }
5173         break;
5174     case 0x70 ... 0x7f: /* jcc Jb */
5175         {
5176             int diff = (int8_t)insn_get(env, s, MO_8);
5177             gen_bnd_jmp(s);
5178             gen_jcc(s, b, diff);
5179         }
5180         break;
5181     case 0x180 ... 0x18f: /* jcc Jv */
5182         {
5183             int diff = (dflag != MO_16
5184                         ? (int32_t)insn_get(env, s, MO_32)
5185                         : (int16_t)insn_get(env, s, MO_16));
5186             gen_bnd_jmp(s);
5187             gen_jcc(s, b, diff);
5188         }
5189         break;
5190 
5191     case 0x190 ... 0x19f: /* setcc Gv */
5192         modrm = x86_ldub_code(env, s);
5193         gen_setcc1(s, b, s->T0);
5194         gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
5195         break;
5196     case 0x140 ... 0x14f: /* cmov Gv, Ev */
5197         if (!(s->cpuid_features & CPUID_CMOV)) {
5198             goto illegal_op;
5199         }
5200         ot = dflag;
5201         modrm = x86_ldub_code(env, s);
5202         reg = ((modrm >> 3) & 7) | REX_R(s);
5203         gen_cmovcc1(env, s, ot, b, modrm, reg);
5204         break;
5205 
5206         /************************/
5207         /* flags */
5208     case 0x9c: /* pushf */
5209         gen_svm_check_intercept(s, SVM_EXIT_PUSHF);
5210         if (check_vm86_iopl(s)) {
5211             gen_update_cc_op(s);
5212             gen_helper_read_eflags(s->T0, tcg_env);
5213             gen_push_v(s, s->T0);
5214         }
5215         break;
5216     case 0x9d: /* popf */
5217         gen_svm_check_intercept(s, SVM_EXIT_POPF);
5218         if (check_vm86_iopl(s)) {
5219             int mask = TF_MASK | AC_MASK | ID_MASK | NT_MASK;
5220 
5221             if (CPL(s) == 0) {
5222                 mask |= IF_MASK | IOPL_MASK;
5223             } else if (CPL(s) <= IOPL(s)) {
5224                 mask |= IF_MASK;
5225             }
5226             if (dflag == MO_16) {
5227                 mask &= 0xffff;
5228             }
5229 
5230             ot = gen_pop_T0(s);
5231             gen_helper_write_eflags(tcg_env, s->T0, tcg_constant_i32(mask));
5232             gen_pop_update(s, ot);
5233             set_cc_op(s, CC_OP_EFLAGS);
5234             /* abort translation because TF/AC flag may change */
5235             s->base.is_jmp = DISAS_EOB_NEXT;
5236         }
5237         break;
5238     case 0x9e: /* sahf */
5239         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5240             goto illegal_op;
5241         tcg_gen_shri_tl(s->T0, cpu_regs[R_EAX], 8);
5242         gen_compute_eflags(s);
5243         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
5244         tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
5245         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0);
5246         break;
5247     case 0x9f: /* lahf */
5248         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5249             goto illegal_op;
5250         gen_compute_eflags(s);
5251         /* Note: gen_compute_eflags() only gives the condition codes */
5252         tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02);
5253         tcg_gen_deposit_tl(cpu_regs[R_EAX], cpu_regs[R_EAX], s->T0, 8, 8);
5254         break;
5255     case 0xf5: /* cmc */
5256         gen_compute_eflags(s);
5257         tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5258         break;
5259     case 0xf8: /* clc */
5260         gen_compute_eflags(s);
5261         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
5262         break;
5263     case 0xf9: /* stc */
5264         gen_compute_eflags(s);
5265         tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5266         break;
5267     case 0xfc: /* cld */
5268         tcg_gen_movi_i32(s->tmp2_i32, 1);
5269         tcg_gen_st_i32(s->tmp2_i32, tcg_env, offsetof(CPUX86State, df));
5270         break;
5271     case 0xfd: /* std */
5272         tcg_gen_movi_i32(s->tmp2_i32, -1);
5273         tcg_gen_st_i32(s->tmp2_i32, tcg_env, offsetof(CPUX86State, df));
5274         break;
5275 
5276         /************************/
5277         /* bit operations */
5278     case 0x1ba: /* bt/bts/btr/btc Gv, im */
5279         ot = dflag;
5280         modrm = x86_ldub_code(env, s);
5281         op = (modrm >> 3) & 7;
5282         mod = (modrm >> 6) & 3;
5283         rm = (modrm & 7) | REX_B(s);
5284         if (mod != 3) {
5285             s->rip_offset = 1;
5286             gen_lea_modrm(env, s, modrm);
5287             if (!(s->prefix & PREFIX_LOCK)) {
5288                 gen_op_ld_v(s, ot, s->T0, s->A0);
5289             }
5290         } else {
5291             gen_op_mov_v_reg(s, ot, s->T0, rm);
5292         }
5293         /* load shift */
5294         val = x86_ldub_code(env, s);
5295         tcg_gen_movi_tl(s->T1, val);
5296         if (op < 4)
5297             goto unknown_op;
5298         op -= 4;
5299         goto bt_op;
5300     case 0x1a3: /* bt Gv, Ev */
5301         op = 0;
5302         goto do_btx;
5303     case 0x1ab: /* bts */
5304         op = 1;
5305         goto do_btx;
5306     case 0x1b3: /* btr */
5307         op = 2;
5308         goto do_btx;
5309     case 0x1bb: /* btc */
5310         op = 3;
5311     do_btx:
5312         ot = dflag;
5313         modrm = x86_ldub_code(env, s);
5314         reg = ((modrm >> 3) & 7) | REX_R(s);
5315         mod = (modrm >> 6) & 3;
5316         rm = (modrm & 7) | REX_B(s);
5317         gen_op_mov_v_reg(s, MO_32, s->T1, reg);
5318         if (mod != 3) {
5319             AddressParts a = gen_lea_modrm_0(env, s, modrm);
5320             /* specific case: we need to add a displacement */
5321             gen_exts(ot, s->T1);
5322             tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot);
5323             tcg_gen_shli_tl(s->tmp0, s->tmp0, ot);
5324             tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0);
5325             gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
5326             if (!(s->prefix & PREFIX_LOCK)) {
5327                 gen_op_ld_v(s, ot, s->T0, s->A0);
5328             }
5329         } else {
5330             gen_op_mov_v_reg(s, ot, s->T0, rm);
5331         }
5332     bt_op:
5333         tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1);
5334         tcg_gen_movi_tl(s->tmp0, 1);
5335         tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1);
5336         if (s->prefix & PREFIX_LOCK) {
5337             switch (op) {
5338             case 0: /* bt */
5339                 /* Needs no atomic ops; we suppressed the normal
5340                    memory load for LOCK above so do it now.  */
5341                 gen_op_ld_v(s, ot, s->T0, s->A0);
5342                 break;
5343             case 1: /* bts */
5344                 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0,
5345                                            s->mem_index, ot | MO_LE);
5346                 break;
5347             case 2: /* btr */
5348                 tcg_gen_not_tl(s->tmp0, s->tmp0);
5349                 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0,
5350                                             s->mem_index, ot | MO_LE);
5351                 break;
5352             default:
5353             case 3: /* btc */
5354                 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0,
5355                                             s->mem_index, ot | MO_LE);
5356                 break;
5357             }
5358             tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
5359         } else {
5360             tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
5361             switch (op) {
5362             case 0: /* bt */
5363                 /* Data already loaded; nothing to do.  */
5364                 break;
5365             case 1: /* bts */
5366                 tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
5367                 break;
5368             case 2: /* btr */
5369                 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0);
5370                 break;
5371             default:
5372             case 3: /* btc */
5373                 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0);
5374                 break;
5375             }
5376             if (op != 0) {
5377                 if (mod != 3) {
5378                     gen_op_st_v(s, ot, s->T0, s->A0);
5379                 } else {
5380                     gen_op_mov_reg_v(s, ot, rm, s->T0);
5381                 }
5382             }
5383         }
5384 
5385         /* Delay all CC updates until after the store above.  Note that
5386            C is the result of the test, Z is unchanged, and the others
5387            are all undefined.  */
5388         switch (s->cc_op) {
5389         case CC_OP_MULB ... CC_OP_MULQ:
5390         case CC_OP_ADDB ... CC_OP_ADDQ:
5391         case CC_OP_ADCB ... CC_OP_ADCQ:
5392         case CC_OP_SUBB ... CC_OP_SUBQ:
5393         case CC_OP_SBBB ... CC_OP_SBBQ:
5394         case CC_OP_LOGICB ... CC_OP_LOGICQ:
5395         case CC_OP_INCB ... CC_OP_INCQ:
5396         case CC_OP_DECB ... CC_OP_DECQ:
5397         case CC_OP_SHLB ... CC_OP_SHLQ:
5398         case CC_OP_SARB ... CC_OP_SARQ:
5399         case CC_OP_BMILGB ... CC_OP_BMILGQ:
5400             /* Z was going to be computed from the non-zero status of CC_DST.
5401                We can get that same Z value (and the new C value) by leaving
5402                CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
5403                same width.  */
5404             tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
5405             set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
5406             break;
5407         default:
5408             /* Otherwise, generate EFLAGS and replace the C bit.  */
5409             gen_compute_eflags(s);
5410             tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4,
5411                                ctz32(CC_C), 1);
5412             break;
5413         }
5414         break;
5415     case 0x1bc: /* bsf / tzcnt */
5416     case 0x1bd: /* bsr / lzcnt */
5417         ot = dflag;
5418         modrm = x86_ldub_code(env, s);
5419         reg = ((modrm >> 3) & 7) | REX_R(s);
5420         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5421         gen_extu(ot, s->T0);
5422 
5423         /* Note that lzcnt and tzcnt are in different extensions.  */
5424         if ((prefixes & PREFIX_REPZ)
5425             && (b & 1
5426                 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
5427                 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
5428             int size = 8 << ot;
5429             /* For lzcnt/tzcnt, C bit is defined related to the input. */
5430             tcg_gen_mov_tl(cpu_cc_src, s->T0);
5431             if (b & 1) {
5432                 /* For lzcnt, reduce the target_ulong result by the
5433                    number of zeros that we expect to find at the top.  */
5434                 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS);
5435                 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size);
5436             } else {
5437                 /* For tzcnt, a zero input must return the operand size.  */
5438                 tcg_gen_ctzi_tl(s->T0, s->T0, size);
5439             }
5440             /* For lzcnt/tzcnt, Z bit is defined related to the result.  */
5441             gen_op_update1_cc(s);
5442             set_cc_op(s, CC_OP_BMILGB + ot);
5443         } else {
5444             /* For bsr/bsf, only the Z bit is defined and it is related
5445                to the input and not the result.  */
5446             tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5447             set_cc_op(s, CC_OP_LOGICB + ot);
5448 
5449             /* ??? The manual says that the output is undefined when the
5450                input is zero, but real hardware leaves it unchanged, and
5451                real programs appear to depend on that.  Accomplish this
5452                by passing the output as the value to return upon zero.  */
5453             if (b & 1) {
5454                 /* For bsr, return the bit index of the first 1 bit,
5455                    not the count of leading zeros.  */
5456                 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
5457                 tcg_gen_clz_tl(s->T0, s->T0, s->T1);
5458                 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1);
5459             } else {
5460                 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]);
5461             }
5462         }
5463         gen_op_mov_reg_v(s, ot, reg, s->T0);
5464         break;
5465         /************************/
5466         /* bcd */
5467     case 0x27: /* daa */
5468         if (CODE64(s))
5469             goto illegal_op;
5470         gen_update_cc_op(s);
5471         gen_helper_daa(tcg_env);
5472         set_cc_op(s, CC_OP_EFLAGS);
5473         break;
5474     case 0x2f: /* das */
5475         if (CODE64(s))
5476             goto illegal_op;
5477         gen_update_cc_op(s);
5478         gen_helper_das(tcg_env);
5479         set_cc_op(s, CC_OP_EFLAGS);
5480         break;
5481     case 0x37: /* aaa */
5482         if (CODE64(s))
5483             goto illegal_op;
5484         gen_update_cc_op(s);
5485         gen_helper_aaa(tcg_env);
5486         set_cc_op(s, CC_OP_EFLAGS);
5487         break;
5488     case 0x3f: /* aas */
5489         if (CODE64(s))
5490             goto illegal_op;
5491         gen_update_cc_op(s);
5492         gen_helper_aas(tcg_env);
5493         set_cc_op(s, CC_OP_EFLAGS);
5494         break;
5495     case 0xd4: /* aam */
5496         if (CODE64(s))
5497             goto illegal_op;
5498         val = x86_ldub_code(env, s);
5499         if (val == 0) {
5500             gen_exception(s, EXCP00_DIVZ);
5501         } else {
5502             gen_helper_aam(tcg_env, tcg_constant_i32(val));
5503             set_cc_op(s, CC_OP_LOGICB);
5504         }
5505         break;
5506     case 0xd5: /* aad */
5507         if (CODE64(s))
5508             goto illegal_op;
5509         val = x86_ldub_code(env, s);
5510         gen_helper_aad(tcg_env, tcg_constant_i32(val));
5511         set_cc_op(s, CC_OP_LOGICB);
5512         break;
5513         /************************/
5514         /* misc */
5515     case 0x90: /* nop */
5516         /* XXX: correct lock test for all insn */
5517         if (prefixes & PREFIX_LOCK) {
5518             goto illegal_op;
5519         }
5520         /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
5521         if (REX_B(s)) {
5522             goto do_xchg_reg_eax;
5523         }
5524         if (prefixes & PREFIX_REPZ) {
5525             gen_update_cc_op(s);
5526             gen_update_eip_cur(s);
5527             gen_helper_pause(tcg_env, cur_insn_len_i32(s));
5528             s->base.is_jmp = DISAS_NORETURN;
5529         }
5530         break;
5531     case 0x9b: /* fwait */
5532         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
5533             (HF_MP_MASK | HF_TS_MASK)) {
5534             gen_exception(s, EXCP07_PREX);
5535         } else {
5536             /* needs to be treated as I/O because of ferr_irq */
5537             translator_io_start(&s->base);
5538             gen_helper_fwait(tcg_env);
5539         }
5540         break;
5541     case 0xcc: /* int3 */
5542         gen_interrupt(s, EXCP03_INT3);
5543         break;
5544     case 0xcd: /* int N */
5545         val = x86_ldub_code(env, s);
5546         if (check_vm86_iopl(s)) {
5547             gen_interrupt(s, val);
5548         }
5549         break;
5550     case 0xce: /* into */
5551         if (CODE64(s))
5552             goto illegal_op;
5553         gen_update_cc_op(s);
5554         gen_update_eip_cur(s);
5555         gen_helper_into(tcg_env, cur_insn_len_i32(s));
5556         break;
5557 #ifdef WANT_ICEBP
5558     case 0xf1: /* icebp (undocumented, exits to external debugger) */
5559         gen_svm_check_intercept(s, SVM_EXIT_ICEBP);
5560         gen_debug(s);
5561         break;
5562 #endif
5563     case 0xfa: /* cli */
5564         if (check_iopl(s)) {
5565             gen_reset_eflags(s, IF_MASK);
5566         }
5567         break;
5568     case 0xfb: /* sti */
5569         if (check_iopl(s)) {
5570             gen_set_eflags(s, IF_MASK);
5571             /* interruptions are enabled only the first insn after sti */
5572             gen_update_eip_next(s);
5573             gen_eob_inhibit_irq(s, true);
5574         }
5575         break;
5576     case 0x62: /* bound */
5577         if (CODE64(s))
5578             goto illegal_op;
5579         ot = dflag;
5580         modrm = x86_ldub_code(env, s);
5581         reg = (modrm >> 3) & 7;
5582         mod = (modrm >> 6) & 3;
5583         if (mod == 3)
5584             goto illegal_op;
5585         gen_op_mov_v_reg(s, ot, s->T0, reg);
5586         gen_lea_modrm(env, s, modrm);
5587         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5588         if (ot == MO_16) {
5589             gen_helper_boundw(tcg_env, s->A0, s->tmp2_i32);
5590         } else {
5591             gen_helper_boundl(tcg_env, s->A0, s->tmp2_i32);
5592         }
5593         break;
5594     case 0x1c8 ... 0x1cf: /* bswap reg */
5595         reg = (b & 7) | REX_B(s);
5596 #ifdef TARGET_X86_64
5597         if (dflag == MO_64) {
5598             tcg_gen_bswap64_i64(cpu_regs[reg], cpu_regs[reg]);
5599             break;
5600         }
5601 #endif
5602         tcg_gen_bswap32_tl(cpu_regs[reg], cpu_regs[reg], TCG_BSWAP_OZ);
5603         break;
5604     case 0xd6: /* salc */
5605         if (CODE64(s))
5606             goto illegal_op;
5607         gen_compute_eflags_c(s, s->T0);
5608         tcg_gen_neg_tl(s->T0, s->T0);
5609         gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
5610         break;
5611     case 0xe0: /* loopnz */
5612     case 0xe1: /* loopz */
5613     case 0xe2: /* loop */
5614     case 0xe3: /* jecxz */
5615         {
5616             TCGLabel *l1, *l2;
5617             int diff = (int8_t)insn_get(env, s, MO_8);
5618 
5619             l1 = gen_new_label();
5620             l2 = gen_new_label();
5621             gen_update_cc_op(s);
5622             b &= 3;
5623             switch(b) {
5624             case 0: /* loopnz */
5625             case 1: /* loopz */
5626                 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
5627                 gen_op_jz_ecx(s, l2);
5628                 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
5629                 break;
5630             case 2: /* loop */
5631                 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
5632                 gen_op_jnz_ecx(s, l1);
5633                 break;
5634             default:
5635             case 3: /* jcxz */
5636                 gen_op_jz_ecx(s, l1);
5637                 break;
5638             }
5639 
5640             gen_set_label(l2);
5641             gen_jmp_rel_csize(s, 0, 1);
5642 
5643             gen_set_label(l1);
5644             gen_jmp_rel(s, dflag, diff, 0);
5645         }
5646         break;
5647     case 0x130: /* wrmsr */
5648     case 0x132: /* rdmsr */
5649         if (check_cpl0(s)) {
5650             gen_update_cc_op(s);
5651             gen_update_eip_cur(s);
5652             if (b & 2) {
5653                 gen_helper_rdmsr(tcg_env);
5654             } else {
5655                 gen_helper_wrmsr(tcg_env);
5656                 s->base.is_jmp = DISAS_EOB_NEXT;
5657             }
5658         }
5659         break;
5660     case 0x131: /* rdtsc */
5661         gen_update_cc_op(s);
5662         gen_update_eip_cur(s);
5663         translator_io_start(&s->base);
5664         gen_helper_rdtsc(tcg_env);
5665         break;
5666     case 0x133: /* rdpmc */
5667         gen_update_cc_op(s);
5668         gen_update_eip_cur(s);
5669         gen_helper_rdpmc(tcg_env);
5670         s->base.is_jmp = DISAS_NORETURN;
5671         break;
5672     case 0x134: /* sysenter */
5673         /* For AMD SYSENTER is not valid in long mode */
5674         if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) {
5675             goto illegal_op;
5676         }
5677         if (!PE(s)) {
5678             gen_exception_gpf(s);
5679         } else {
5680             gen_helper_sysenter(tcg_env);
5681             s->base.is_jmp = DISAS_EOB_ONLY;
5682         }
5683         break;
5684     case 0x135: /* sysexit */
5685         /* For AMD SYSEXIT is not valid in long mode */
5686         if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) {
5687             goto illegal_op;
5688         }
5689         if (!PE(s) || CPL(s) != 0) {
5690             gen_exception_gpf(s);
5691         } else {
5692             gen_helper_sysexit(tcg_env, tcg_constant_i32(dflag - 1));
5693             s->base.is_jmp = DISAS_EOB_ONLY;
5694         }
5695         break;
5696     case 0x105: /* syscall */
5697         /* For Intel SYSCALL is only valid in long mode */
5698         if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) {
5699             goto illegal_op;
5700         }
5701         gen_update_cc_op(s);
5702         gen_update_eip_cur(s);
5703         gen_helper_syscall(tcg_env, cur_insn_len_i32(s));
5704         /* TF handling for the syscall insn is different. The TF bit is  checked
5705            after the syscall insn completes. This allows #DB to not be
5706            generated after one has entered CPL0 if TF is set in FMASK.  */
5707         gen_eob_worker(s, false, true);
5708         break;
5709     case 0x107: /* sysret */
5710         /* For Intel SYSRET is only valid in long mode */
5711         if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) {
5712             goto illegal_op;
5713         }
5714         if (!PE(s) || CPL(s) != 0) {
5715             gen_exception_gpf(s);
5716         } else {
5717             gen_helper_sysret(tcg_env, tcg_constant_i32(dflag - 1));
5718             /* condition codes are modified only in long mode */
5719             if (LMA(s)) {
5720                 set_cc_op(s, CC_OP_EFLAGS);
5721             }
5722             /* TF handling for the sysret insn is different. The TF bit is
5723                checked after the sysret insn completes. This allows #DB to be
5724                generated "as if" the syscall insn in userspace has just
5725                completed.  */
5726             gen_eob_worker(s, false, true);
5727         }
5728         break;
5729     case 0x1a2: /* cpuid */
5730         gen_update_cc_op(s);
5731         gen_update_eip_cur(s);
5732         gen_helper_cpuid(tcg_env);
5733         break;
5734     case 0xf4: /* hlt */
5735         if (check_cpl0(s)) {
5736             gen_update_cc_op(s);
5737             gen_update_eip_cur(s);
5738             gen_helper_hlt(tcg_env, cur_insn_len_i32(s));
5739             s->base.is_jmp = DISAS_NORETURN;
5740         }
5741         break;
5742     case 0x100:
5743         modrm = x86_ldub_code(env, s);
5744         mod = (modrm >> 6) & 3;
5745         op = (modrm >> 3) & 7;
5746         switch(op) {
5747         case 0: /* sldt */
5748             if (!PE(s) || VM86(s))
5749                 goto illegal_op;
5750             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5751                 break;
5752             }
5753             gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ);
5754             tcg_gen_ld32u_tl(s->T0, tcg_env,
5755                              offsetof(CPUX86State, ldt.selector));
5756             ot = mod == 3 ? dflag : MO_16;
5757             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5758             break;
5759         case 2: /* lldt */
5760             if (!PE(s) || VM86(s))
5761                 goto illegal_op;
5762             if (check_cpl0(s)) {
5763                 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE);
5764                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5765                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5766                 gen_helper_lldt(tcg_env, s->tmp2_i32);
5767             }
5768             break;
5769         case 1: /* str */
5770             if (!PE(s) || VM86(s))
5771                 goto illegal_op;
5772             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5773                 break;
5774             }
5775             gen_svm_check_intercept(s, SVM_EXIT_TR_READ);
5776             tcg_gen_ld32u_tl(s->T0, tcg_env,
5777                              offsetof(CPUX86State, tr.selector));
5778             ot = mod == 3 ? dflag : MO_16;
5779             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5780             break;
5781         case 3: /* ltr */
5782             if (!PE(s) || VM86(s))
5783                 goto illegal_op;
5784             if (check_cpl0(s)) {
5785                 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE);
5786                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5787                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5788                 gen_helper_ltr(tcg_env, s->tmp2_i32);
5789             }
5790             break;
5791         case 4: /* verr */
5792         case 5: /* verw */
5793             if (!PE(s) || VM86(s))
5794                 goto illegal_op;
5795             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5796             gen_update_cc_op(s);
5797             if (op == 4) {
5798                 gen_helper_verr(tcg_env, s->T0);
5799             } else {
5800                 gen_helper_verw(tcg_env, s->T0);
5801             }
5802             set_cc_op(s, CC_OP_EFLAGS);
5803             break;
5804         default:
5805             goto unknown_op;
5806         }
5807         break;
5808 
5809     case 0x101:
5810         modrm = x86_ldub_code(env, s);
5811         switch (modrm) {
5812         CASE_MODRM_MEM_OP(0): /* sgdt */
5813             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5814                 break;
5815             }
5816             gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ);
5817             gen_lea_modrm(env, s, modrm);
5818             tcg_gen_ld32u_tl(s->T0,
5819                              tcg_env, offsetof(CPUX86State, gdt.limit));
5820             gen_op_st_v(s, MO_16, s->T0, s->A0);
5821             gen_add_A0_im(s, 2);
5822             tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base));
5823             if (dflag == MO_16) {
5824                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
5825             }
5826             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
5827             break;
5828 
5829         case 0xc8: /* monitor */
5830             if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
5831                 goto illegal_op;
5832             }
5833             gen_update_cc_op(s);
5834             gen_update_eip_cur(s);
5835             tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
5836             gen_extu(s->aflag, s->A0);
5837             gen_add_A0_ds_seg(s);
5838             gen_helper_monitor(tcg_env, s->A0);
5839             break;
5840 
5841         case 0xc9: /* mwait */
5842             if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
5843                 goto illegal_op;
5844             }
5845             gen_update_cc_op(s);
5846             gen_update_eip_cur(s);
5847             gen_helper_mwait(tcg_env, cur_insn_len_i32(s));
5848             s->base.is_jmp = DISAS_NORETURN;
5849             break;
5850 
5851         case 0xca: /* clac */
5852             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
5853                 || CPL(s) != 0) {
5854                 goto illegal_op;
5855             }
5856             gen_reset_eflags(s, AC_MASK);
5857             s->base.is_jmp = DISAS_EOB_NEXT;
5858             break;
5859 
5860         case 0xcb: /* stac */
5861             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
5862                 || CPL(s) != 0) {
5863                 goto illegal_op;
5864             }
5865             gen_set_eflags(s, AC_MASK);
5866             s->base.is_jmp = DISAS_EOB_NEXT;
5867             break;
5868 
5869         CASE_MODRM_MEM_OP(1): /* sidt */
5870             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5871                 break;
5872             }
5873             gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ);
5874             gen_lea_modrm(env, s, modrm);
5875             tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.limit));
5876             gen_op_st_v(s, MO_16, s->T0, s->A0);
5877             gen_add_A0_im(s, 2);
5878             tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base));
5879             if (dflag == MO_16) {
5880                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
5881             }
5882             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
5883             break;
5884 
5885         case 0xd0: /* xgetbv */
5886             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
5887                 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
5888                                  | PREFIX_REPZ | PREFIX_REPNZ))) {
5889                 goto illegal_op;
5890             }
5891             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
5892             gen_helper_xgetbv(s->tmp1_i64, tcg_env, s->tmp2_i32);
5893             tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
5894             break;
5895 
5896         case 0xd1: /* xsetbv */
5897             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
5898                 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
5899                                  | PREFIX_REPZ | PREFIX_REPNZ))) {
5900                 goto illegal_op;
5901             }
5902             gen_svm_check_intercept(s, SVM_EXIT_XSETBV);
5903             if (!check_cpl0(s)) {
5904                 break;
5905             }
5906             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
5907                                   cpu_regs[R_EDX]);
5908             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
5909             gen_helper_xsetbv(tcg_env, s->tmp2_i32, s->tmp1_i64);
5910             /* End TB because translation flags may change.  */
5911             s->base.is_jmp = DISAS_EOB_NEXT;
5912             break;
5913 
5914         case 0xd8: /* VMRUN */
5915             if (!SVME(s) || !PE(s)) {
5916                 goto illegal_op;
5917             }
5918             if (!check_cpl0(s)) {
5919                 break;
5920             }
5921             gen_update_cc_op(s);
5922             gen_update_eip_cur(s);
5923             gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1),
5924                              cur_insn_len_i32(s));
5925             tcg_gen_exit_tb(NULL, 0);
5926             s->base.is_jmp = DISAS_NORETURN;
5927             break;
5928 
5929         case 0xd9: /* VMMCALL */
5930             if (!SVME(s)) {
5931                 goto illegal_op;
5932             }
5933             gen_update_cc_op(s);
5934             gen_update_eip_cur(s);
5935             gen_helper_vmmcall(tcg_env);
5936             break;
5937 
5938         case 0xda: /* VMLOAD */
5939             if (!SVME(s) || !PE(s)) {
5940                 goto illegal_op;
5941             }
5942             if (!check_cpl0(s)) {
5943                 break;
5944             }
5945             gen_update_cc_op(s);
5946             gen_update_eip_cur(s);
5947             gen_helper_vmload(tcg_env, tcg_constant_i32(s->aflag - 1));
5948             break;
5949 
5950         case 0xdb: /* VMSAVE */
5951             if (!SVME(s) || !PE(s)) {
5952                 goto illegal_op;
5953             }
5954             if (!check_cpl0(s)) {
5955                 break;
5956             }
5957             gen_update_cc_op(s);
5958             gen_update_eip_cur(s);
5959             gen_helper_vmsave(tcg_env, tcg_constant_i32(s->aflag - 1));
5960             break;
5961 
5962         case 0xdc: /* STGI */
5963             if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
5964                 || !PE(s)) {
5965                 goto illegal_op;
5966             }
5967             if (!check_cpl0(s)) {
5968                 break;
5969             }
5970             gen_update_cc_op(s);
5971             gen_helper_stgi(tcg_env);
5972             s->base.is_jmp = DISAS_EOB_NEXT;
5973             break;
5974 
5975         case 0xdd: /* CLGI */
5976             if (!SVME(s) || !PE(s)) {
5977                 goto illegal_op;
5978             }
5979             if (!check_cpl0(s)) {
5980                 break;
5981             }
5982             gen_update_cc_op(s);
5983             gen_update_eip_cur(s);
5984             gen_helper_clgi(tcg_env);
5985             break;
5986 
5987         case 0xde: /* SKINIT */
5988             if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
5989                 || !PE(s)) {
5990                 goto illegal_op;
5991             }
5992             gen_svm_check_intercept(s, SVM_EXIT_SKINIT);
5993             /* If not intercepted, not implemented -- raise #UD. */
5994             goto illegal_op;
5995 
5996         case 0xdf: /* INVLPGA */
5997             if (!SVME(s) || !PE(s)) {
5998                 goto illegal_op;
5999             }
6000             if (!check_cpl0(s)) {
6001                 break;
6002             }
6003             gen_svm_check_intercept(s, SVM_EXIT_INVLPGA);
6004             if (s->aflag == MO_64) {
6005                 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
6006             } else {
6007                 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
6008             }
6009             gen_helper_flush_page(tcg_env, s->A0);
6010             s->base.is_jmp = DISAS_EOB_NEXT;
6011             break;
6012 
6013         CASE_MODRM_MEM_OP(2): /* lgdt */
6014             if (!check_cpl0(s)) {
6015                 break;
6016             }
6017             gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE);
6018             gen_lea_modrm(env, s, modrm);
6019             gen_op_ld_v(s, MO_16, s->T1, s->A0);
6020             gen_add_A0_im(s, 2);
6021             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
6022             if (dflag == MO_16) {
6023                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
6024             }
6025             tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base));
6026             tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, gdt.limit));
6027             break;
6028 
6029         CASE_MODRM_MEM_OP(3): /* lidt */
6030             if (!check_cpl0(s)) {
6031                 break;
6032             }
6033             gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE);
6034             gen_lea_modrm(env, s, modrm);
6035             gen_op_ld_v(s, MO_16, s->T1, s->A0);
6036             gen_add_A0_im(s, 2);
6037             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
6038             if (dflag == MO_16) {
6039                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
6040             }
6041             tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base));
6042             tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, idt.limit));
6043             break;
6044 
6045         CASE_MODRM_OP(4): /* smsw */
6046             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
6047                 break;
6048             }
6049             gen_svm_check_intercept(s, SVM_EXIT_READ_CR0);
6050             tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, cr[0]));
6051             /*
6052              * In 32-bit mode, the higher 16 bits of the destination
6053              * register are undefined.  In practice CR0[31:0] is stored
6054              * just like in 64-bit mode.
6055              */
6056             mod = (modrm >> 6) & 3;
6057             ot = (mod != 3 ? MO_16 : s->dflag);
6058             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
6059             break;
6060         case 0xee: /* rdpkru */
6061             if (prefixes & PREFIX_LOCK) {
6062                 goto illegal_op;
6063             }
6064             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
6065             gen_helper_rdpkru(s->tmp1_i64, tcg_env, s->tmp2_i32);
6066             tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
6067             break;
6068         case 0xef: /* wrpkru */
6069             if (prefixes & PREFIX_LOCK) {
6070                 goto illegal_op;
6071             }
6072             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6073                                   cpu_regs[R_EDX]);
6074             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
6075             gen_helper_wrpkru(tcg_env, s->tmp2_i32, s->tmp1_i64);
6076             break;
6077 
6078         CASE_MODRM_OP(6): /* lmsw */
6079             if (!check_cpl0(s)) {
6080                 break;
6081             }
6082             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
6083             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
6084             /*
6085              * Only the 4 lower bits of CR0 are modified.
6086              * PE cannot be set to zero if already set to one.
6087              */
6088             tcg_gen_ld_tl(s->T1, tcg_env, offsetof(CPUX86State, cr[0]));
6089             tcg_gen_andi_tl(s->T0, s->T0, 0xf);
6090             tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
6091             tcg_gen_or_tl(s->T0, s->T0, s->T1);
6092             gen_helper_write_crN(tcg_env, tcg_constant_i32(0), s->T0);
6093             s->base.is_jmp = DISAS_EOB_NEXT;
6094             break;
6095 
6096         CASE_MODRM_MEM_OP(7): /* invlpg */
6097             if (!check_cpl0(s)) {
6098                 break;
6099             }
6100             gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
6101             gen_lea_modrm(env, s, modrm);
6102             gen_helper_flush_page(tcg_env, s->A0);
6103             s->base.is_jmp = DISAS_EOB_NEXT;
6104             break;
6105 
6106         case 0xf8: /* swapgs */
6107 #ifdef TARGET_X86_64
6108             if (CODE64(s)) {
6109                 if (check_cpl0(s)) {
6110                     tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
6111                     tcg_gen_ld_tl(cpu_seg_base[R_GS], tcg_env,
6112                                   offsetof(CPUX86State, kernelgsbase));
6113                     tcg_gen_st_tl(s->T0, tcg_env,
6114                                   offsetof(CPUX86State, kernelgsbase));
6115                 }
6116                 break;
6117             }
6118 #endif
6119             goto illegal_op;
6120 
6121         case 0xf9: /* rdtscp */
6122             if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
6123                 goto illegal_op;
6124             }
6125             gen_update_cc_op(s);
6126             gen_update_eip_cur(s);
6127             translator_io_start(&s->base);
6128             gen_helper_rdtsc(tcg_env);
6129             gen_helper_rdpid(s->T0, tcg_env);
6130             gen_op_mov_reg_v(s, dflag, R_ECX, s->T0);
6131             break;
6132 
6133         default:
6134             goto unknown_op;
6135         }
6136         break;
6137 
6138     case 0x108: /* invd */
6139     case 0x109: /* wbinvd; wbnoinvd with REPZ prefix */
6140         if (check_cpl0(s)) {
6141             gen_svm_check_intercept(s, (b & 1) ? SVM_EXIT_WBINVD : SVM_EXIT_INVD);
6142             /* nothing to do */
6143         }
6144         break;
6145     case 0x63: /* arpl or movslS (x86_64) */
6146 #ifdef TARGET_X86_64
6147         if (CODE64(s)) {
6148             int d_ot;
6149             /* d_ot is the size of destination */
6150             d_ot = dflag;
6151 
6152             modrm = x86_ldub_code(env, s);
6153             reg = ((modrm >> 3) & 7) | REX_R(s);
6154             mod = (modrm >> 6) & 3;
6155             rm = (modrm & 7) | REX_B(s);
6156 
6157             if (mod == 3) {
6158                 gen_op_mov_v_reg(s, MO_32, s->T0, rm);
6159                 /* sign extend */
6160                 if (d_ot == MO_64) {
6161                     tcg_gen_ext32s_tl(s->T0, s->T0);
6162                 }
6163                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
6164             } else {
6165                 gen_lea_modrm(env, s, modrm);
6166                 gen_op_ld_v(s, MO_32 | MO_SIGN, s->T0, s->A0);
6167                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
6168             }
6169         } else
6170 #endif
6171         {
6172             TCGLabel *label1;
6173             TCGv t0, t1, t2;
6174 
6175             if (!PE(s) || VM86(s))
6176                 goto illegal_op;
6177             t0 = tcg_temp_new();
6178             t1 = tcg_temp_new();
6179             t2 = tcg_temp_new();
6180             ot = MO_16;
6181             modrm = x86_ldub_code(env, s);
6182             reg = (modrm >> 3) & 7;
6183             mod = (modrm >> 6) & 3;
6184             rm = modrm & 7;
6185             if (mod != 3) {
6186                 gen_lea_modrm(env, s, modrm);
6187                 gen_op_ld_v(s, ot, t0, s->A0);
6188             } else {
6189                 gen_op_mov_v_reg(s, ot, t0, rm);
6190             }
6191             gen_op_mov_v_reg(s, ot, t1, reg);
6192             tcg_gen_andi_tl(s->tmp0, t0, 3);
6193             tcg_gen_andi_tl(t1, t1, 3);
6194             tcg_gen_movi_tl(t2, 0);
6195             label1 = gen_new_label();
6196             tcg_gen_brcond_tl(TCG_COND_GE, s->tmp0, t1, label1);
6197             tcg_gen_andi_tl(t0, t0, ~3);
6198             tcg_gen_or_tl(t0, t0, t1);
6199             tcg_gen_movi_tl(t2, CC_Z);
6200             gen_set_label(label1);
6201             if (mod != 3) {
6202                 gen_op_st_v(s, ot, t0, s->A0);
6203            } else {
6204                 gen_op_mov_reg_v(s, ot, rm, t0);
6205             }
6206             gen_compute_eflags(s);
6207             tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
6208             tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
6209         }
6210         break;
6211     case 0x102: /* lar */
6212     case 0x103: /* lsl */
6213         {
6214             TCGLabel *label1;
6215             TCGv t0;
6216             if (!PE(s) || VM86(s))
6217                 goto illegal_op;
6218             ot = dflag != MO_16 ? MO_32 : MO_16;
6219             modrm = x86_ldub_code(env, s);
6220             reg = ((modrm >> 3) & 7) | REX_R(s);
6221             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
6222             t0 = tcg_temp_new();
6223             gen_update_cc_op(s);
6224             if (b == 0x102) {
6225                 gen_helper_lar(t0, tcg_env, s->T0);
6226             } else {
6227                 gen_helper_lsl(t0, tcg_env, s->T0);
6228             }
6229             tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z);
6230             label1 = gen_new_label();
6231             tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1);
6232             gen_op_mov_reg_v(s, ot, reg, t0);
6233             gen_set_label(label1);
6234             set_cc_op(s, CC_OP_EFLAGS);
6235         }
6236         break;
6237     case 0x118:
6238         modrm = x86_ldub_code(env, s);
6239         mod = (modrm >> 6) & 3;
6240         op = (modrm >> 3) & 7;
6241         switch(op) {
6242         case 0: /* prefetchnta */
6243         case 1: /* prefetchnt0 */
6244         case 2: /* prefetchnt0 */
6245         case 3: /* prefetchnt0 */
6246             if (mod == 3)
6247                 goto illegal_op;
6248             gen_nop_modrm(env, s, modrm);
6249             /* nothing more to do */
6250             break;
6251         default: /* nop (multi byte) */
6252             gen_nop_modrm(env, s, modrm);
6253             break;
6254         }
6255         break;
6256     case 0x11a:
6257         modrm = x86_ldub_code(env, s);
6258         if (s->flags & HF_MPX_EN_MASK) {
6259             mod = (modrm >> 6) & 3;
6260             reg = ((modrm >> 3) & 7) | REX_R(s);
6261             if (prefixes & PREFIX_REPZ) {
6262                 /* bndcl */
6263                 if (reg >= 4
6264                     || (prefixes & PREFIX_LOCK)
6265                     || s->aflag == MO_16) {
6266                     goto illegal_op;
6267                 }
6268                 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
6269             } else if (prefixes & PREFIX_REPNZ) {
6270                 /* bndcu */
6271                 if (reg >= 4
6272                     || (prefixes & PREFIX_LOCK)
6273                     || s->aflag == MO_16) {
6274                     goto illegal_op;
6275                 }
6276                 TCGv_i64 notu = tcg_temp_new_i64();
6277                 tcg_gen_not_i64(notu, cpu_bndu[reg]);
6278                 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
6279             } else if (prefixes & PREFIX_DATA) {
6280                 /* bndmov -- from reg/mem */
6281                 if (reg >= 4 || s->aflag == MO_16) {
6282                     goto illegal_op;
6283                 }
6284                 if (mod == 3) {
6285                     int reg2 = (modrm & 7) | REX_B(s);
6286                     if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
6287                         goto illegal_op;
6288                     }
6289                     if (s->flags & HF_MPX_IU_MASK) {
6290                         tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
6291                         tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
6292                     }
6293                 } else {
6294                     gen_lea_modrm(env, s, modrm);
6295                     if (CODE64(s)) {
6296                         tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
6297                                             s->mem_index, MO_LEUQ);
6298                         tcg_gen_addi_tl(s->A0, s->A0, 8);
6299                         tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
6300                                             s->mem_index, MO_LEUQ);
6301                     } else {
6302                         tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
6303                                             s->mem_index, MO_LEUL);
6304                         tcg_gen_addi_tl(s->A0, s->A0, 4);
6305                         tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
6306                                             s->mem_index, MO_LEUL);
6307                     }
6308                     /* bnd registers are now in-use */
6309                     gen_set_hflag(s, HF_MPX_IU_MASK);
6310                 }
6311             } else if (mod != 3) {
6312                 /* bndldx */
6313                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6314                 if (reg >= 4
6315                     || (prefixes & PREFIX_LOCK)
6316                     || s->aflag == MO_16
6317                     || a.base < -1) {
6318                     goto illegal_op;
6319                 }
6320                 if (a.base >= 0) {
6321                     tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
6322                 } else {
6323                     tcg_gen_movi_tl(s->A0, 0);
6324                 }
6325                 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
6326                 if (a.index >= 0) {
6327                     tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
6328                 } else {
6329                     tcg_gen_movi_tl(s->T0, 0);
6330                 }
6331                 if (CODE64(s)) {
6332                     gen_helper_bndldx64(cpu_bndl[reg], tcg_env, s->A0, s->T0);
6333                     tcg_gen_ld_i64(cpu_bndu[reg], tcg_env,
6334                                    offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
6335                 } else {
6336                     gen_helper_bndldx32(cpu_bndu[reg], tcg_env, s->A0, s->T0);
6337                     tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
6338                     tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
6339                 }
6340                 gen_set_hflag(s, HF_MPX_IU_MASK);
6341             }
6342         }
6343         gen_nop_modrm(env, s, modrm);
6344         break;
6345     case 0x11b:
6346         modrm = x86_ldub_code(env, s);
6347         if (s->flags & HF_MPX_EN_MASK) {
6348             mod = (modrm >> 6) & 3;
6349             reg = ((modrm >> 3) & 7) | REX_R(s);
6350             if (mod != 3 && (prefixes & PREFIX_REPZ)) {
6351                 /* bndmk */
6352                 if (reg >= 4
6353                     || (prefixes & PREFIX_LOCK)
6354                     || s->aflag == MO_16) {
6355                     goto illegal_op;
6356                 }
6357                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6358                 if (a.base >= 0) {
6359                     tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
6360                     if (!CODE64(s)) {
6361                         tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
6362                     }
6363                 } else if (a.base == -1) {
6364                     /* no base register has lower bound of 0 */
6365                     tcg_gen_movi_i64(cpu_bndl[reg], 0);
6366                 } else {
6367                     /* rip-relative generates #ud */
6368                     goto illegal_op;
6369                 }
6370                 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false));
6371                 if (!CODE64(s)) {
6372                     tcg_gen_ext32u_tl(s->A0, s->A0);
6373                 }
6374                 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0);
6375                 /* bnd registers are now in-use */
6376                 gen_set_hflag(s, HF_MPX_IU_MASK);
6377                 break;
6378             } else if (prefixes & PREFIX_REPNZ) {
6379                 /* bndcn */
6380                 if (reg >= 4
6381                     || (prefixes & PREFIX_LOCK)
6382                     || s->aflag == MO_16) {
6383                     goto illegal_op;
6384                 }
6385                 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
6386             } else if (prefixes & PREFIX_DATA) {
6387                 /* bndmov -- to reg/mem */
6388                 if (reg >= 4 || s->aflag == MO_16) {
6389                     goto illegal_op;
6390                 }
6391                 if (mod == 3) {
6392                     int reg2 = (modrm & 7) | REX_B(s);
6393                     if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
6394                         goto illegal_op;
6395                     }
6396                     if (s->flags & HF_MPX_IU_MASK) {
6397                         tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
6398                         tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
6399                     }
6400                 } else {
6401                     gen_lea_modrm(env, s, modrm);
6402                     if (CODE64(s)) {
6403                         tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
6404                                             s->mem_index, MO_LEUQ);
6405                         tcg_gen_addi_tl(s->A0, s->A0, 8);
6406                         tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
6407                                             s->mem_index, MO_LEUQ);
6408                     } else {
6409                         tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
6410                                             s->mem_index, MO_LEUL);
6411                         tcg_gen_addi_tl(s->A0, s->A0, 4);
6412                         tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
6413                                             s->mem_index, MO_LEUL);
6414                     }
6415                 }
6416             } else if (mod != 3) {
6417                 /* bndstx */
6418                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6419                 if (reg >= 4
6420                     || (prefixes & PREFIX_LOCK)
6421                     || s->aflag == MO_16
6422                     || a.base < -1) {
6423                     goto illegal_op;
6424                 }
6425                 if (a.base >= 0) {
6426                     tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
6427                 } else {
6428                     tcg_gen_movi_tl(s->A0, 0);
6429                 }
6430                 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
6431                 if (a.index >= 0) {
6432                     tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
6433                 } else {
6434                     tcg_gen_movi_tl(s->T0, 0);
6435                 }
6436                 if (CODE64(s)) {
6437                     gen_helper_bndstx64(tcg_env, s->A0, s->T0,
6438                                         cpu_bndl[reg], cpu_bndu[reg]);
6439                 } else {
6440                     gen_helper_bndstx32(tcg_env, s->A0, s->T0,
6441                                         cpu_bndl[reg], cpu_bndu[reg]);
6442                 }
6443             }
6444         }
6445         gen_nop_modrm(env, s, modrm);
6446         break;
6447     case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
6448         modrm = x86_ldub_code(env, s);
6449         gen_nop_modrm(env, s, modrm);
6450         break;
6451 
6452     case 0x120: /* mov reg, crN */
6453     case 0x122: /* mov crN, reg */
6454         if (!check_cpl0(s)) {
6455             break;
6456         }
6457         modrm = x86_ldub_code(env, s);
6458         /*
6459          * Ignore the mod bits (assume (modrm&0xc0)==0xc0).
6460          * AMD documentation (24594.pdf) and testing of Intel 386 and 486
6461          * processors all show that the mod bits are assumed to be 1's,
6462          * regardless of actual values.
6463          */
6464         rm = (modrm & 7) | REX_B(s);
6465         reg = ((modrm >> 3) & 7) | REX_R(s);
6466         switch (reg) {
6467         case 0:
6468             if ((prefixes & PREFIX_LOCK) &&
6469                 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
6470                 reg = 8;
6471             }
6472             break;
6473         case 2:
6474         case 3:
6475         case 4:
6476         case 8:
6477             break;
6478         default:
6479             goto unknown_op;
6480         }
6481         ot  = (CODE64(s) ? MO_64 : MO_32);
6482 
6483         translator_io_start(&s->base);
6484         if (b & 2) {
6485             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
6486             gen_op_mov_v_reg(s, ot, s->T0, rm);
6487             gen_helper_write_crN(tcg_env, tcg_constant_i32(reg), s->T0);
6488             s->base.is_jmp = DISAS_EOB_NEXT;
6489         } else {
6490             gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
6491             gen_helper_read_crN(s->T0, tcg_env, tcg_constant_i32(reg));
6492             gen_op_mov_reg_v(s, ot, rm, s->T0);
6493         }
6494         break;
6495 
6496     case 0x121: /* mov reg, drN */
6497     case 0x123: /* mov drN, reg */
6498         if (check_cpl0(s)) {
6499             modrm = x86_ldub_code(env, s);
6500             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
6501              * AMD documentation (24594.pdf) and testing of
6502              * intel 386 and 486 processors all show that the mod bits
6503              * are assumed to be 1's, regardless of actual values.
6504              */
6505             rm = (modrm & 7) | REX_B(s);
6506             reg = ((modrm >> 3) & 7) | REX_R(s);
6507             if (CODE64(s))
6508                 ot = MO_64;
6509             else
6510                 ot = MO_32;
6511             if (reg >= 8) {
6512                 goto illegal_op;
6513             }
6514             if (b & 2) {
6515                 gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg);
6516                 gen_op_mov_v_reg(s, ot, s->T0, rm);
6517                 tcg_gen_movi_i32(s->tmp2_i32, reg);
6518                 gen_helper_set_dr(tcg_env, s->tmp2_i32, s->T0);
6519                 s->base.is_jmp = DISAS_EOB_NEXT;
6520             } else {
6521                 gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
6522                 tcg_gen_movi_i32(s->tmp2_i32, reg);
6523                 gen_helper_get_dr(s->T0, tcg_env, s->tmp2_i32);
6524                 gen_op_mov_reg_v(s, ot, rm, s->T0);
6525             }
6526         }
6527         break;
6528     case 0x106: /* clts */
6529         if (check_cpl0(s)) {
6530             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
6531             gen_helper_clts(tcg_env);
6532             /* abort block because static cpu state changed */
6533             s->base.is_jmp = DISAS_EOB_NEXT;
6534         }
6535         break;
6536     /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
6537     case 0x1c3: /* MOVNTI reg, mem */
6538         if (!(s->cpuid_features & CPUID_SSE2))
6539             goto illegal_op;
6540         ot = mo_64_32(dflag);
6541         modrm = x86_ldub_code(env, s);
6542         mod = (modrm >> 6) & 3;
6543         if (mod == 3)
6544             goto illegal_op;
6545         reg = ((modrm >> 3) & 7) | REX_R(s);
6546         /* generate a generic store */
6547         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
6548         break;
6549     case 0x1ae:
6550         modrm = x86_ldub_code(env, s);
6551         switch (modrm) {
6552         CASE_MODRM_MEM_OP(0): /* fxsave */
6553             if (!(s->cpuid_features & CPUID_FXSR)
6554                 || (prefixes & PREFIX_LOCK)) {
6555                 goto illegal_op;
6556             }
6557             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
6558                 gen_exception(s, EXCP07_PREX);
6559                 break;
6560             }
6561             gen_lea_modrm(env, s, modrm);
6562             gen_helper_fxsave(tcg_env, s->A0);
6563             break;
6564 
6565         CASE_MODRM_MEM_OP(1): /* fxrstor */
6566             if (!(s->cpuid_features & CPUID_FXSR)
6567                 || (prefixes & PREFIX_LOCK)) {
6568                 goto illegal_op;
6569             }
6570             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
6571                 gen_exception(s, EXCP07_PREX);
6572                 break;
6573             }
6574             gen_lea_modrm(env, s, modrm);
6575             gen_helper_fxrstor(tcg_env, s->A0);
6576             break;
6577 
6578         CASE_MODRM_MEM_OP(2): /* ldmxcsr */
6579             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
6580                 goto illegal_op;
6581             }
6582             if (s->flags & HF_TS_MASK) {
6583                 gen_exception(s, EXCP07_PREX);
6584                 break;
6585             }
6586             gen_lea_modrm(env, s, modrm);
6587             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
6588             gen_helper_ldmxcsr(tcg_env, s->tmp2_i32);
6589             break;
6590 
6591         CASE_MODRM_MEM_OP(3): /* stmxcsr */
6592             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
6593                 goto illegal_op;
6594             }
6595             if (s->flags & HF_TS_MASK) {
6596                 gen_exception(s, EXCP07_PREX);
6597                 break;
6598             }
6599             gen_helper_update_mxcsr(tcg_env);
6600             gen_lea_modrm(env, s, modrm);
6601             tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, mxcsr));
6602             gen_op_st_v(s, MO_32, s->T0, s->A0);
6603             break;
6604 
6605         CASE_MODRM_MEM_OP(4): /* xsave */
6606             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6607                 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
6608                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
6609                 goto illegal_op;
6610             }
6611             gen_lea_modrm(env, s, modrm);
6612             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6613                                   cpu_regs[R_EDX]);
6614             gen_helper_xsave(tcg_env, s->A0, s->tmp1_i64);
6615             break;
6616 
6617         CASE_MODRM_MEM_OP(5): /* xrstor */
6618             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6619                 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
6620                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
6621                 goto illegal_op;
6622             }
6623             gen_lea_modrm(env, s, modrm);
6624             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6625                                   cpu_regs[R_EDX]);
6626             gen_helper_xrstor(tcg_env, s->A0, s->tmp1_i64);
6627             /* XRSTOR is how MPX is enabled, which changes how
6628                we translate.  Thus we need to end the TB.  */
6629             s->base.is_jmp = DISAS_EOB_NEXT;
6630             break;
6631 
6632         CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
6633             if (prefixes & PREFIX_LOCK) {
6634                 goto illegal_op;
6635             }
6636             if (prefixes & PREFIX_DATA) {
6637                 /* clwb */
6638                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
6639                     goto illegal_op;
6640                 }
6641                 gen_nop_modrm(env, s, modrm);
6642             } else {
6643                 /* xsaveopt */
6644                 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6645                     || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
6646                     || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
6647                     goto illegal_op;
6648                 }
6649                 gen_lea_modrm(env, s, modrm);
6650                 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6651                                       cpu_regs[R_EDX]);
6652                 gen_helper_xsaveopt(tcg_env, s->A0, s->tmp1_i64);
6653             }
6654             break;
6655 
6656         CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
6657             if (prefixes & PREFIX_LOCK) {
6658                 goto illegal_op;
6659             }
6660             if (prefixes & PREFIX_DATA) {
6661                 /* clflushopt */
6662                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
6663                     goto illegal_op;
6664                 }
6665             } else {
6666                 /* clflush */
6667                 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
6668                     || !(s->cpuid_features & CPUID_CLFLUSH)) {
6669                     goto illegal_op;
6670                 }
6671             }
6672             gen_nop_modrm(env, s, modrm);
6673             break;
6674 
6675         case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
6676         case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
6677         case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
6678         case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
6679             if (CODE64(s)
6680                 && (prefixes & PREFIX_REPZ)
6681                 && !(prefixes & PREFIX_LOCK)
6682                 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
6683                 TCGv base, treg, src, dst;
6684 
6685                 /* Preserve hflags bits by testing CR4 at runtime.  */
6686                 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK);
6687                 gen_helper_cr4_testbit(tcg_env, s->tmp2_i32);
6688 
6689                 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
6690                 treg = cpu_regs[(modrm & 7) | REX_B(s)];
6691 
6692                 if (modrm & 0x10) {
6693                     /* wr*base */
6694                     dst = base, src = treg;
6695                 } else {
6696                     /* rd*base */
6697                     dst = treg, src = base;
6698                 }
6699 
6700                 if (s->dflag == MO_32) {
6701                     tcg_gen_ext32u_tl(dst, src);
6702                 } else {
6703                     tcg_gen_mov_tl(dst, src);
6704                 }
6705                 break;
6706             }
6707             goto unknown_op;
6708 
6709         case 0xf8: /* sfence / pcommit */
6710             if (prefixes & PREFIX_DATA) {
6711                 /* pcommit */
6712                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
6713                     || (prefixes & PREFIX_LOCK)) {
6714                     goto illegal_op;
6715                 }
6716                 break;
6717             }
6718             /* fallthru */
6719         case 0xf9 ... 0xff: /* sfence */
6720             if (!(s->cpuid_features & CPUID_SSE)
6721                 || (prefixes & PREFIX_LOCK)) {
6722                 goto illegal_op;
6723             }
6724             tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
6725             break;
6726         case 0xe8 ... 0xef: /* lfence */
6727             if (!(s->cpuid_features & CPUID_SSE)
6728                 || (prefixes & PREFIX_LOCK)) {
6729                 goto illegal_op;
6730             }
6731             tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
6732             break;
6733         case 0xf0 ... 0xf7: /* mfence */
6734             if (!(s->cpuid_features & CPUID_SSE2)
6735                 || (prefixes & PREFIX_LOCK)) {
6736                 goto illegal_op;
6737             }
6738             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
6739             break;
6740 
6741         default:
6742             goto unknown_op;
6743         }
6744         break;
6745 
6746     case 0x10d: /* 3DNow! prefetch(w) */
6747         modrm = x86_ldub_code(env, s);
6748         mod = (modrm >> 6) & 3;
6749         if (mod == 3)
6750             goto illegal_op;
6751         gen_nop_modrm(env, s, modrm);
6752         break;
6753     case 0x1aa: /* rsm */
6754         gen_svm_check_intercept(s, SVM_EXIT_RSM);
6755         if (!(s->flags & HF_SMM_MASK))
6756             goto illegal_op;
6757 #ifdef CONFIG_USER_ONLY
6758         /* we should not be in SMM mode */
6759         g_assert_not_reached();
6760 #else
6761         gen_update_cc_op(s);
6762         gen_update_eip_next(s);
6763         gen_helper_rsm(tcg_env);
6764 #endif /* CONFIG_USER_ONLY */
6765         s->base.is_jmp = DISAS_EOB_ONLY;
6766         break;
6767     case 0x1b8: /* SSE4.2 popcnt */
6768         if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
6769              PREFIX_REPZ)
6770             goto illegal_op;
6771         if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
6772             goto illegal_op;
6773 
6774         modrm = x86_ldub_code(env, s);
6775         reg = ((modrm >> 3) & 7) | REX_R(s);
6776 
6777         if (s->prefix & PREFIX_DATA) {
6778             ot = MO_16;
6779         } else {
6780             ot = mo_64_32(dflag);
6781         }
6782 
6783         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6784         gen_extu(ot, s->T0);
6785         tcg_gen_mov_tl(cpu_cc_src, s->T0);
6786         tcg_gen_ctpop_tl(s->T0, s->T0);
6787         gen_op_mov_reg_v(s, ot, reg, s->T0);
6788 
6789         set_cc_op(s, CC_OP_POPCNT);
6790         break;
6791     case 0x10e ... 0x117:
6792     case 0x128 ... 0x12f:
6793     case 0x138 ... 0x13a:
6794     case 0x150 ... 0x179:
6795     case 0x17c ... 0x17f:
6796     case 0x1c2:
6797     case 0x1c4 ... 0x1c6:
6798     case 0x1d0 ... 0x1fe:
6799         disas_insn_new(s, cpu, b);
6800         break;
6801     default:
6802         goto unknown_op;
6803     }
6804     return true;
6805  illegal_op:
6806     gen_illegal_opcode(s);
6807     return true;
6808  unknown_op:
6809     gen_unknown_opcode(env, s);
6810     return true;
6811 }
6812 
tcg_x86_init(void)6813 void tcg_x86_init(void)
6814 {
6815     static const char reg_names[CPU_NB_REGS][4] = {
6816 #ifdef TARGET_X86_64
6817         [R_EAX] = "rax",
6818         [R_EBX] = "rbx",
6819         [R_ECX] = "rcx",
6820         [R_EDX] = "rdx",
6821         [R_ESI] = "rsi",
6822         [R_EDI] = "rdi",
6823         [R_EBP] = "rbp",
6824         [R_ESP] = "rsp",
6825         [8]  = "r8",
6826         [9]  = "r9",
6827         [10] = "r10",
6828         [11] = "r11",
6829         [12] = "r12",
6830         [13] = "r13",
6831         [14] = "r14",
6832         [15] = "r15",
6833 #else
6834         [R_EAX] = "eax",
6835         [R_EBX] = "ebx",
6836         [R_ECX] = "ecx",
6837         [R_EDX] = "edx",
6838         [R_ESI] = "esi",
6839         [R_EDI] = "edi",
6840         [R_EBP] = "ebp",
6841         [R_ESP] = "esp",
6842 #endif
6843     };
6844     static const char eip_name[] = {
6845 #ifdef TARGET_X86_64
6846         "rip"
6847 #else
6848         "eip"
6849 #endif
6850     };
6851     static const char seg_base_names[6][8] = {
6852         [R_CS] = "cs_base",
6853         [R_DS] = "ds_base",
6854         [R_ES] = "es_base",
6855         [R_FS] = "fs_base",
6856         [R_GS] = "gs_base",
6857         [R_SS] = "ss_base",
6858     };
6859     static const char bnd_regl_names[4][8] = {
6860         "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
6861     };
6862     static const char bnd_regu_names[4][8] = {
6863         "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
6864     };
6865     int i;
6866 
6867     cpu_cc_op = tcg_global_mem_new_i32(tcg_env,
6868                                        offsetof(CPUX86State, cc_op), "cc_op");
6869     cpu_cc_dst = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_dst),
6870                                     "cc_dst");
6871     cpu_cc_src = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src),
6872                                     "cc_src");
6873     cpu_cc_src2 = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src2),
6874                                      "cc_src2");
6875     cpu_eip = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, eip), eip_name);
6876 
6877     for (i = 0; i < CPU_NB_REGS; ++i) {
6878         cpu_regs[i] = tcg_global_mem_new(tcg_env,
6879                                          offsetof(CPUX86State, regs[i]),
6880                                          reg_names[i]);
6881     }
6882 
6883     for (i = 0; i < 6; ++i) {
6884         cpu_seg_base[i]
6885             = tcg_global_mem_new(tcg_env,
6886                                  offsetof(CPUX86State, segs[i].base),
6887                                  seg_base_names[i]);
6888     }
6889 
6890     for (i = 0; i < 4; ++i) {
6891         cpu_bndl[i]
6892             = tcg_global_mem_new_i64(tcg_env,
6893                                      offsetof(CPUX86State, bnd_regs[i].lb),
6894                                      bnd_regl_names[i]);
6895         cpu_bndu[i]
6896             = tcg_global_mem_new_i64(tcg_env,
6897                                      offsetof(CPUX86State, bnd_regs[i].ub),
6898                                      bnd_regu_names[i]);
6899     }
6900 }
6901 
i386_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cpu)6902 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
6903 {
6904     DisasContext *dc = container_of(dcbase, DisasContext, base);
6905     CPUX86State *env = cpu_env(cpu);
6906     uint32_t flags = dc->base.tb->flags;
6907     uint32_t cflags = tb_cflags(dc->base.tb);
6908     int cpl = (flags >> HF_CPL_SHIFT) & 3;
6909     int iopl = (flags >> IOPL_SHIFT) & 3;
6910 
6911     dc->cs_base = dc->base.tb->cs_base;
6912     dc->pc_save = dc->base.pc_next;
6913     dc->flags = flags;
6914 #ifndef CONFIG_USER_ONLY
6915     dc->cpl = cpl;
6916     dc->iopl = iopl;
6917 #endif
6918 
6919     /* We make some simplifying assumptions; validate they're correct. */
6920     g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
6921     g_assert(CPL(dc) == cpl);
6922     g_assert(IOPL(dc) == iopl);
6923     g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
6924     g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
6925     g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0));
6926     g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
6927     g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
6928     g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
6929     g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0));
6930     g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0));
6931 
6932     dc->cc_op = CC_OP_DYNAMIC;
6933     dc->cc_op_dirty = false;
6934     dc->popl_esp_hack = 0;
6935     /* select memory access functions */
6936     dc->mem_index = cpu_mmu_index(env, false);
6937     dc->cpuid_features = env->features[FEAT_1_EDX];
6938     dc->cpuid_ext_features = env->features[FEAT_1_ECX];
6939     dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
6940     dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
6941     dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
6942     dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX];
6943     dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
6944     dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
6945                     (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
6946     /*
6947      * If jmp_opt, we want to handle each string instruction individually.
6948      * For icount also disable repz optimization so that each iteration
6949      * is accounted separately.
6950      */
6951     dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT);
6952 
6953     dc->T0 = tcg_temp_new();
6954     dc->T1 = tcg_temp_new();
6955     dc->A0 = tcg_temp_new();
6956 
6957     dc->tmp0 = tcg_temp_new();
6958     dc->tmp1_i64 = tcg_temp_new_i64();
6959     dc->tmp2_i32 = tcg_temp_new_i32();
6960     dc->tmp3_i32 = tcg_temp_new_i32();
6961     dc->tmp4 = tcg_temp_new();
6962     dc->cc_srcT = tcg_temp_new();
6963 }
6964 
i386_tr_tb_start(DisasContextBase * db,CPUState * cpu)6965 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
6966 {
6967 }
6968 
i386_tr_insn_start(DisasContextBase * dcbase,CPUState * cpu)6969 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
6970 {
6971     DisasContext *dc = container_of(dcbase, DisasContext, base);
6972     target_ulong pc_arg = dc->base.pc_next;
6973 
6974     dc->prev_insn_end = tcg_last_op();
6975     if (tb_cflags(dcbase->tb) & CF_PCREL) {
6976         pc_arg &= ~TARGET_PAGE_MASK;
6977     }
6978     tcg_gen_insn_start(pc_arg, dc->cc_op);
6979 }
6980 
i386_tr_translate_insn(DisasContextBase * dcbase,CPUState * cpu)6981 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
6982 {
6983     DisasContext *dc = container_of(dcbase, DisasContext, base);
6984 
6985 #ifdef TARGET_VSYSCALL_PAGE
6986     /*
6987      * Detect entry into the vsyscall page and invoke the syscall.
6988      */
6989     if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) {
6990         gen_exception(dc, EXCP_VSYSCALL);
6991         dc->base.pc_next = dc->pc + 1;
6992         return;
6993     }
6994 #endif
6995 
6996     if (disas_insn(dc, cpu)) {
6997         target_ulong pc_next = dc->pc;
6998         dc->base.pc_next = pc_next;
6999 
7000         if (dc->base.is_jmp == DISAS_NEXT) {
7001             if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
7002                 /*
7003                  * If single step mode, we generate only one instruction and
7004                  * generate an exception.
7005                  * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7006                  * the flag and abort the translation to give the irqs a
7007                  * chance to happen.
7008                  */
7009                 dc->base.is_jmp = DISAS_EOB_NEXT;
7010             } else if (!is_same_page(&dc->base, pc_next)) {
7011                 dc->base.is_jmp = DISAS_TOO_MANY;
7012             }
7013         }
7014     }
7015 }
7016 
i386_tr_tb_stop(DisasContextBase * dcbase,CPUState * cpu)7017 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
7018 {
7019     DisasContext *dc = container_of(dcbase, DisasContext, base);
7020 
7021     switch (dc->base.is_jmp) {
7022     case DISAS_NORETURN:
7023         break;
7024     case DISAS_TOO_MANY:
7025         gen_update_cc_op(dc);
7026         gen_jmp_rel_csize(dc, 0, 0);
7027         break;
7028     case DISAS_EOB_NEXT:
7029         gen_update_cc_op(dc);
7030         gen_update_eip_cur(dc);
7031         /* fall through */
7032     case DISAS_EOB_ONLY:
7033         gen_eob(dc);
7034         break;
7035     case DISAS_EOB_INHIBIT_IRQ:
7036         gen_update_cc_op(dc);
7037         gen_update_eip_cur(dc);
7038         gen_eob_inhibit_irq(dc, true);
7039         break;
7040     case DISAS_JUMP:
7041         gen_jr(dc);
7042         break;
7043     default:
7044         g_assert_not_reached();
7045     }
7046 }
7047 
i386_tr_disas_log(const DisasContextBase * dcbase,CPUState * cpu,FILE * logfile)7048 static void i386_tr_disas_log(const DisasContextBase *dcbase,
7049                               CPUState *cpu, FILE *logfile)
7050 {
7051     DisasContext *dc = container_of(dcbase, DisasContext, base);
7052 
7053     fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first));
7054     target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size);
7055 }
7056 
7057 static const TranslatorOps i386_tr_ops = {
7058     .init_disas_context = i386_tr_init_disas_context,
7059     .tb_start           = i386_tr_tb_start,
7060     .insn_start         = i386_tr_insn_start,
7061     .translate_insn     = i386_tr_translate_insn,
7062     .tb_stop            = i386_tr_tb_stop,
7063     .disas_log          = i386_tr_disas_log,
7064 };
7065 
7066 /* generate intermediate code for basic block 'tb'.  */
gen_intermediate_code(CPUState * cpu,TranslationBlock * tb,int * max_insns,target_ulong pc,void * host_pc)7067 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
7068                            target_ulong pc, void *host_pc)
7069 {
7070     DisasContext dc;
7071 
7072     translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base);
7073 }
7074