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