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