xref: /openbmc/qemu/target/i386/tcg/translate.c (revision c94bee4cd6693c1c65ba43bb8970cf909dec378b)
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 "exec/exec-all.h"
24  #include "tcg/tcg-op.h"
25  #include "tcg/tcg-op-gvec.h"
26  #include "exec/translator.h"
27  #include "fpu/softfloat.h"
28  
29  #include "exec/helper-proto.h"
30  #include "exec/helper-gen.h"
31  #include "helper-tcg.h"
32  #include "decode-new.h"
33  
34  #include "exec/log.h"
35  
36  #define HELPER_H "helper.h"
37  #include "exec/helper-info.c.inc"
38  #undef  HELPER_H
39  
40  /* Fixes for Windows namespace pollution.  */
41  #undef IN
42  #undef OUT
43  
44  #define PREFIX_REPZ   0x01
45  #define PREFIX_REPNZ  0x02
46  #define PREFIX_LOCK   0x04
47  #define PREFIX_DATA   0x08
48  #define PREFIX_ADR    0x10
49  #define PREFIX_VEX    0x20
50  #define PREFIX_REX    0x40
51  
52  #ifdef TARGET_X86_64
53  # define ctztl  ctz64
54  # define clztl  clz64
55  #else
56  # define ctztl  ctz32
57  # define clztl  clz32
58  #endif
59  
60  /* For a switch indexed by MODRM, match all memory operands for a given OP.  */
61  #define CASE_MODRM_MEM_OP(OP) \
62      case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
63      case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
64      case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
65  
66  #define CASE_MODRM_OP(OP) \
67      case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
68      case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
69      case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
70      case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
71  
72  //#define MACRO_TEST   1
73  
74  /* global register indexes */
75  static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2;
76  static TCGv cpu_eip;
77  static TCGv_i32 cpu_cc_op;
78  static TCGv cpu_regs[CPU_NB_REGS];
79  static TCGv cpu_seg_base[6];
80  static TCGv_i64 cpu_bndl[4];
81  static TCGv_i64 cpu_bndu[4];
82  
83  typedef struct DisasContext {
84      DisasContextBase base;
85  
86      target_ulong pc;       /* pc = eip + cs_base */
87      target_ulong cs_base;  /* base of CS segment */
88      target_ulong pc_save;
89  
90      MemOp aflag;
91      MemOp dflag;
92  
93      int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
94      uint8_t prefix;
95  
96      bool has_modrm;
97      uint8_t modrm;
98  
99  #ifndef CONFIG_USER_ONLY
100      uint8_t cpl;   /* code priv level */
101      uint8_t iopl;  /* i/o priv level */
102  #endif
103      uint8_t vex_l;  /* vex vector length */
104      uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
105      uint8_t popl_esp_hack; /* for correct popl with esp base handling */
106      uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
107  
108  #ifdef TARGET_X86_64
109      uint8_t rex_r;
110      uint8_t rex_x;
111      uint8_t rex_b;
112  #endif
113      bool vex_w; /* used by AVX even on 32-bit processors */
114      bool jmp_opt; /* use direct block chaining for direct jumps */
115      bool repz_opt; /* optimize jumps within repz instructions */
116      bool cc_op_dirty;
117  
118      CCOp cc_op;  /* current CC operation */
119      int mem_index; /* select memory access functions */
120      uint32_t flags; /* all execution flags */
121      int cpuid_features;
122      int cpuid_ext_features;
123      int cpuid_ext2_features;
124      int cpuid_ext3_features;
125      int cpuid_7_0_ebx_features;
126      int cpuid_7_0_ecx_features;
127      int cpuid_7_1_eax_features;
128      int cpuid_xsave_features;
129  
130      /* TCG local temps */
131      TCGv cc_srcT;
132      TCGv A0;
133      TCGv T0;
134      TCGv T1;
135  
136      /* TCG local register indexes (only used inside old micro ops) */
137      TCGv tmp0;
138      TCGv tmp4;
139      TCGv_i32 tmp2_i32;
140      TCGv_i32 tmp3_i32;
141      TCGv_i64 tmp1_i64;
142  
143      sigjmp_buf jmpbuf;
144      TCGOp *prev_insn_start;
145      TCGOp *prev_insn_end;
146  } DisasContext;
147  
148  /*
149   * Point EIP to next instruction before ending translation.
150   * For instructions that can change hflags.
151   */
152  #define DISAS_EOB_NEXT         DISAS_TARGET_0
153  
154  /*
155   * Point EIP to next instruction and set HF_INHIBIT_IRQ if not
156   * already set.  For instructions that activate interrupt shadow.
157   */
158  #define DISAS_EOB_INHIBIT_IRQ  DISAS_TARGET_1
159  
160  /*
161   * Return to the main loop; EIP might have already been updated
162   * but even in that case do not use lookup_and_goto_ptr().
163   */
164  #define DISAS_EOB_ONLY         DISAS_TARGET_2
165  
166  /*
167   * EIP has already been updated.  For jumps that wish to use
168   * lookup_and_goto_ptr()
169   */
170  #define DISAS_JUMP             DISAS_TARGET_3
171  
172  /*
173   * EIP has already been updated.  Use updated value of
174   * EFLAGS.TF to determine singlestep trap (SYSCALL/SYSRET).
175   */
176  #define DISAS_EOB_RECHECK_TF   DISAS_TARGET_4
177  
178  /* The environment in which user-only runs is constrained. */
179  #ifdef CONFIG_USER_ONLY
180  #define PE(S)     true
181  #define CPL(S)    3
182  #define IOPL(S)   0
183  #define SVME(S)   false
184  #define GUEST(S)  false
185  #else
186  #define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
187  #define CPL(S)    ((S)->cpl)
188  #define IOPL(S)   ((S)->iopl)
189  #define SVME(S)   (((S)->flags & HF_SVME_MASK) != 0)
190  #define GUEST(S)  (((S)->flags & HF_GUEST_MASK) != 0)
191  #endif
192  #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
193  #define VM86(S)   false
194  #define CODE32(S) true
195  #define SS32(S)   true
196  #define ADDSEG(S) false
197  #else
198  #define VM86(S)   (((S)->flags & HF_VM_MASK) != 0)
199  #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
200  #define SS32(S)   (((S)->flags & HF_SS32_MASK) != 0)
201  #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0)
202  #endif
203  #if !defined(TARGET_X86_64)
204  #define CODE64(S) false
205  #elif defined(CONFIG_USER_ONLY)
206  #define CODE64(S) true
207  #else
208  #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
209  #endif
210  #if defined(CONFIG_USER_ONLY) || defined(TARGET_X86_64)
211  #define LMA(S)    (((S)->flags & HF_LMA_MASK) != 0)
212  #else
213  #define LMA(S)    false
214  #endif
215  
216  #ifdef TARGET_X86_64
217  #define REX_PREFIX(S)  (((S)->prefix & PREFIX_REX) != 0)
218  #define REX_W(S)       ((S)->vex_w)
219  #define REX_R(S)       ((S)->rex_r + 0)
220  #define REX_X(S)       ((S)->rex_x + 0)
221  #define REX_B(S)       ((S)->rex_b + 0)
222  #else
223  #define REX_PREFIX(S)  false
224  #define REX_W(S)       false
225  #define REX_R(S)       0
226  #define REX_X(S)       0
227  #define REX_B(S)       0
228  #endif
229  
230  /*
231   * Many sysemu-only helpers are not reachable for user-only.
232   * Define stub generators here, so that we need not either sprinkle
233   * ifdefs through the translator, nor provide the helper function.
234   */
235  #define STUB_HELPER(NAME, ...) \
236      static inline void gen_helper_##NAME(__VA_ARGS__) \
237      { qemu_build_not_reached(); }
238  
239  #ifdef CONFIG_USER_ONLY
240  STUB_HELPER(clgi, TCGv_env env)
241  STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
242  STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port)
243  STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port)
244  STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port)
245  STUB_HELPER(monitor, TCGv_env env, TCGv addr)
246  STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
247  STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
248  STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
249  STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
250  STUB_HELPER(stgi, TCGv_env env)
251  STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type)
252  STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag)
253  STUB_HELPER(vmmcall, TCGv_env env)
254  STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs)
255  STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag)
256  STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val)
257  #endif
258  
259  static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num);
260  static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num);
261  static void gen_exception_gpf(DisasContext *s);
262  
263  /* i386 shift ops */
264  enum {
265      OP_ROL,
266      OP_ROR,
267      OP_RCL,
268      OP_RCR,
269      OP_SHL,
270      OP_SHR,
271      OP_SHL1, /* undocumented */
272      OP_SAR = 7,
273  };
274  
275  enum {
276      JCC_O,
277      JCC_B,
278      JCC_Z,
279      JCC_BE,
280      JCC_S,
281      JCC_P,
282      JCC_L,
283      JCC_LE,
284  };
285  
286  enum {
287      USES_CC_DST  = 1,
288      USES_CC_SRC  = 2,
289      USES_CC_SRC2 = 4,
290      USES_CC_SRCT = 8,
291  };
292  
293  /* Bit set if the global variable is live after setting CC_OP to X.  */
294  static const uint8_t cc_op_live_[] = {
295      [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
296      [CC_OP_EFLAGS] = USES_CC_SRC,
297      [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
298      [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
299      [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
300      [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
301      [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
302      [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
303      [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
304      [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
305      [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
306      [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
307      [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
308      [CC_OP_BLSIB ... CC_OP_BLSIQ] = USES_CC_DST | USES_CC_SRC,
309      [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
310      [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
311      [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
312      [CC_OP_POPCNT] = USES_CC_DST,
313  };
314  
cc_op_live(CCOp op)315  static uint8_t cc_op_live(CCOp op)
316  {
317      uint8_t result;
318      assert(op >= 0 && op < ARRAY_SIZE(cc_op_live_));
319  
320      /*
321       * Check that the array is fully populated.  A zero entry would correspond
322       * to a fixed value of EFLAGS, which can be obtained with CC_OP_EFLAGS
323       * as well.
324       */
325      result = cc_op_live_[op];
326      assert(result);
327      return result;
328  }
329  
set_cc_op_1(DisasContext * s,CCOp op,bool dirty)330  static void set_cc_op_1(DisasContext *s, CCOp op, bool dirty)
331  {
332      int dead;
333  
334      if (s->cc_op == op) {
335          return;
336      }
337  
338      /* Discard CC computation that will no longer be used.  */
339      dead = cc_op_live(s->cc_op) & ~cc_op_live(op);
340      if (dead & USES_CC_DST) {
341          tcg_gen_discard_tl(cpu_cc_dst);
342      }
343      if (dead & USES_CC_SRC) {
344          tcg_gen_discard_tl(cpu_cc_src);
345      }
346      if (dead & USES_CC_SRC2) {
347          tcg_gen_discard_tl(cpu_cc_src2);
348      }
349      if (dead & USES_CC_SRCT) {
350          tcg_gen_discard_tl(s->cc_srcT);
351      }
352  
353      if (dirty && s->cc_op == CC_OP_DYNAMIC) {
354          tcg_gen_discard_i32(cpu_cc_op);
355      }
356      s->cc_op_dirty = dirty;
357      s->cc_op = op;
358  }
359  
set_cc_op(DisasContext * s,CCOp op)360  static void set_cc_op(DisasContext *s, CCOp op)
361  {
362      /*
363       * The DYNAMIC setting is translator only, everything else
364       * will be spilled later.
365       */
366      set_cc_op_1(s, op, op != CC_OP_DYNAMIC);
367  }
368  
assume_cc_op(DisasContext * s,CCOp op)369  static void assume_cc_op(DisasContext *s, CCOp op)
370  {
371      set_cc_op_1(s, op, false);
372  }
373  
gen_update_cc_op(DisasContext * s)374  static void gen_update_cc_op(DisasContext *s)
375  {
376      if (s->cc_op_dirty) {
377          tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
378          s->cc_op_dirty = false;
379      }
380  }
381  
382  #ifdef TARGET_X86_64
383  
384  #define NB_OP_SIZES 4
385  
386  #else /* !TARGET_X86_64 */
387  
388  #define NB_OP_SIZES 3
389  
390  #endif /* !TARGET_X86_64 */
391  
392  #if HOST_BIG_ENDIAN
393  #define REG_B_OFFSET (sizeof(target_ulong) - 1)
394  #define REG_H_OFFSET (sizeof(target_ulong) - 2)
395  #define REG_W_OFFSET (sizeof(target_ulong) - 2)
396  #define REG_L_OFFSET (sizeof(target_ulong) - 4)
397  #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
398  #else
399  #define REG_B_OFFSET 0
400  #define REG_H_OFFSET 1
401  #define REG_W_OFFSET 0
402  #define REG_L_OFFSET 0
403  #define REG_LH_OFFSET 4
404  #endif
405  
406  /* In instruction encodings for byte register accesses the
407   * register number usually indicates "low 8 bits of register N";
408   * however there are some special cases where N 4..7 indicates
409   * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
410   * true for this special case, false otherwise.
411   */
byte_reg_is_xH(DisasContext * s,int reg)412  static inline bool byte_reg_is_xH(DisasContext *s, int reg)
413  {
414      /* Any time the REX prefix is present, byte registers are uniform */
415      if (reg < 4 || REX_PREFIX(s)) {
416          return false;
417      }
418      return true;
419  }
420  
421  /* Select the size of a push/pop operation.  */
mo_pushpop(DisasContext * s,MemOp ot)422  static inline MemOp mo_pushpop(DisasContext *s, MemOp ot)
423  {
424      if (CODE64(s)) {
425          return ot == MO_16 ? MO_16 : MO_64;
426      } else {
427          return ot;
428      }
429  }
430  
431  /* Select the size of the stack pointer.  */
mo_stacksize(DisasContext * s)432  static inline MemOp mo_stacksize(DisasContext *s)
433  {
434      return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
435  }
436  
437  /* Compute the result of writing t0 to the OT-sized register REG.
438   *
439   * If DEST is NULL, store the result into the register and return the
440   * register's TCGv.
441   *
442   * If DEST is not NULL, store the result into DEST and return the
443   * register's TCGv.
444   */
gen_op_deposit_reg_v(DisasContext * s,MemOp ot,int reg,TCGv dest,TCGv t0)445  static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest, TCGv t0)
446  {
447      switch(ot) {
448      case MO_8:
449          if (byte_reg_is_xH(s, reg)) {
450              dest = dest ? dest : cpu_regs[reg - 4];
451              tcg_gen_deposit_tl(dest, cpu_regs[reg - 4], t0, 8, 8);
452              return cpu_regs[reg - 4];
453          }
454          dest = dest ? dest : cpu_regs[reg];
455          tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 8);
456          break;
457      case MO_16:
458          dest = dest ? dest : cpu_regs[reg];
459          tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 16);
460          break;
461      case MO_32:
462          /* For x86_64, this sets the higher half of register to zero.
463             For i386, this is equivalent to a mov. */
464          dest = dest ? dest : cpu_regs[reg];
465          tcg_gen_ext32u_tl(dest, t0);
466          break;
467  #ifdef TARGET_X86_64
468      case MO_64:
469          dest = dest ? dest : cpu_regs[reg];
470          tcg_gen_mov_tl(dest, t0);
471          break;
472  #endif
473      default:
474          g_assert_not_reached();
475      }
476      return cpu_regs[reg];
477  }
478  
gen_op_mov_reg_v(DisasContext * s,MemOp ot,int reg,TCGv t0)479  static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0)
480  {
481      gen_op_deposit_reg_v(s, ot, reg, NULL, t0);
482  }
483  
484  static inline
gen_op_mov_v_reg(DisasContext * s,MemOp ot,TCGv t0,int reg)485  void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg)
486  {
487      if (ot == MO_8 && byte_reg_is_xH(s, reg)) {
488          tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
489      } else {
490          tcg_gen_mov_tl(t0, cpu_regs[reg]);
491      }
492  }
493  
gen_add_A0_im(DisasContext * s,int val)494  static void gen_add_A0_im(DisasContext *s, int val)
495  {
496      tcg_gen_addi_tl(s->A0, s->A0, val);
497      if (!CODE64(s)) {
498          tcg_gen_ext32u_tl(s->A0, s->A0);
499      }
500  }
501  
gen_op_jmp_v(DisasContext * s,TCGv dest)502  static inline void gen_op_jmp_v(DisasContext *s, TCGv dest)
503  {
504      tcg_gen_mov_tl(cpu_eip, dest);
505      s->pc_save = -1;
506  }
507  
508  static inline
gen_op_add_reg_im(DisasContext * s,MemOp size,int reg,int32_t val)509  void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val)
510  {
511      tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val);
512      gen_op_mov_reg_v(s, size, reg, s->tmp0);
513  }
514  
gen_op_add_reg(DisasContext * s,MemOp size,int reg,TCGv val)515  static inline void gen_op_add_reg(DisasContext *s, MemOp size, int reg, TCGv val)
516  {
517      tcg_gen_add_tl(s->tmp0, cpu_regs[reg], val);
518      gen_op_mov_reg_v(s, size, reg, s->tmp0);
519  }
520  
gen_op_ld_v(DisasContext * s,int idx,TCGv t0,TCGv a0)521  static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
522  {
523      tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
524  }
525  
gen_op_st_v(DisasContext * s,int idx,TCGv t0,TCGv a0)526  static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
527  {
528      tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
529  }
530  
gen_update_eip_next(DisasContext * s)531  static void gen_update_eip_next(DisasContext *s)
532  {
533      assert(s->pc_save != -1);
534      if (tb_cflags(s->base.tb) & CF_PCREL) {
535          tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save);
536      } else if (CODE64(s)) {
537          tcg_gen_movi_tl(cpu_eip, s->pc);
538      } else {
539          tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->pc - s->cs_base));
540      }
541      s->pc_save = s->pc;
542  }
543  
gen_update_eip_cur(DisasContext * s)544  static void gen_update_eip_cur(DisasContext *s)
545  {
546      assert(s->pc_save != -1);
547      if (tb_cflags(s->base.tb) & CF_PCREL) {
548          tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save);
549      } else if (CODE64(s)) {
550          tcg_gen_movi_tl(cpu_eip, s->base.pc_next);
551      } else {
552          tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->base.pc_next - s->cs_base));
553      }
554      s->pc_save = s->base.pc_next;
555  }
556  
cur_insn_len(DisasContext * s)557  static int cur_insn_len(DisasContext *s)
558  {
559      return s->pc - s->base.pc_next;
560  }
561  
cur_insn_len_i32(DisasContext * s)562  static TCGv_i32 cur_insn_len_i32(DisasContext *s)
563  {
564      return tcg_constant_i32(cur_insn_len(s));
565  }
566  
eip_next_i32(DisasContext * s)567  static TCGv_i32 eip_next_i32(DisasContext *s)
568  {
569      assert(s->pc_save != -1);
570      /*
571       * This function has two users: lcall_real (always 16-bit mode), and
572       * iret_protected (16, 32, or 64-bit mode).  IRET only uses the value
573       * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is
574       * why passing a 32-bit value isn't broken.  To avoid using this where
575       * we shouldn't, return -1 in 64-bit mode so that execution goes into
576       * the weeds quickly.
577       */
578      if (CODE64(s)) {
579          return tcg_constant_i32(-1);
580      }
581      if (tb_cflags(s->base.tb) & CF_PCREL) {
582          TCGv_i32 ret = tcg_temp_new_i32();
583          tcg_gen_trunc_tl_i32(ret, cpu_eip);
584          tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save);
585          return ret;
586      } else {
587          return tcg_constant_i32(s->pc - s->cs_base);
588      }
589  }
590  
eip_next_tl(DisasContext * s)591  static TCGv eip_next_tl(DisasContext *s)
592  {
593      assert(s->pc_save != -1);
594      if (tb_cflags(s->base.tb) & CF_PCREL) {
595          TCGv ret = tcg_temp_new();
596          tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save);
597          return ret;
598      } else if (CODE64(s)) {
599          return tcg_constant_tl(s->pc);
600      } else {
601          return tcg_constant_tl((uint32_t)(s->pc - s->cs_base));
602      }
603  }
604  
eip_cur_tl(DisasContext * s)605  static TCGv eip_cur_tl(DisasContext *s)
606  {
607      assert(s->pc_save != -1);
608      if (tb_cflags(s->base.tb) & CF_PCREL) {
609          TCGv ret = tcg_temp_new();
610          tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save);
611          return ret;
612      } else if (CODE64(s)) {
613          return tcg_constant_tl(s->base.pc_next);
614      } else {
615          return tcg_constant_tl((uint32_t)(s->base.pc_next - s->cs_base));
616      }
617  }
618  
619  /* Compute SEG:REG into DEST.  SEG is selected from the override segment
620     (OVR_SEG) and the default segment (DEF_SEG).  OVR_SEG may be -1 to
621     indicate no override.  */
gen_lea_v_seg_dest(DisasContext * s,MemOp aflag,TCGv dest,TCGv a0,int def_seg,int ovr_seg)622  static void gen_lea_v_seg_dest(DisasContext *s, MemOp aflag, TCGv dest, TCGv a0,
623                                 int def_seg, int ovr_seg)
624  {
625      switch (aflag) {
626  #ifdef TARGET_X86_64
627      case MO_64:
628          if (ovr_seg < 0) {
629              tcg_gen_mov_tl(dest, a0);
630              return;
631          }
632          break;
633  #endif
634      case MO_32:
635          /* 32 bit address */
636          if (ovr_seg < 0 && ADDSEG(s)) {
637              ovr_seg = def_seg;
638          }
639          if (ovr_seg < 0) {
640              tcg_gen_ext32u_tl(dest, a0);
641              return;
642          }
643          break;
644      case MO_16:
645          /* 16 bit address */
646          tcg_gen_ext16u_tl(dest, a0);
647          a0 = dest;
648          if (ovr_seg < 0) {
649              if (ADDSEG(s)) {
650                  ovr_seg = def_seg;
651              } else {
652                  return;
653              }
654          }
655          break;
656      default:
657          g_assert_not_reached();
658      }
659  
660      if (ovr_seg >= 0) {
661          TCGv seg = cpu_seg_base[ovr_seg];
662  
663          if (aflag == MO_64) {
664              tcg_gen_add_tl(dest, a0, seg);
665          } else if (CODE64(s)) {
666              tcg_gen_ext32u_tl(dest, a0);
667              tcg_gen_add_tl(dest, dest, seg);
668          } else {
669              tcg_gen_add_tl(dest, a0, seg);
670              tcg_gen_ext32u_tl(dest, dest);
671          }
672      }
673  }
674  
gen_lea_v_seg(DisasContext * s,TCGv a0,int def_seg,int ovr_seg)675  static void gen_lea_v_seg(DisasContext *s, TCGv a0,
676                            int def_seg, int ovr_seg)
677  {
678      gen_lea_v_seg_dest(s, s->aflag, s->A0, a0, def_seg, ovr_seg);
679  }
680  
gen_string_movl_A0_ESI(DisasContext * s)681  static inline void gen_string_movl_A0_ESI(DisasContext *s)
682  {
683      gen_lea_v_seg(s, cpu_regs[R_ESI], R_DS, s->override);
684  }
685  
gen_string_movl_A0_EDI(DisasContext * s)686  static inline void gen_string_movl_A0_EDI(DisasContext *s)
687  {
688      gen_lea_v_seg(s, cpu_regs[R_EDI], R_ES, -1);
689  }
690  
gen_compute_Dshift(DisasContext * s,MemOp ot)691  static inline TCGv gen_compute_Dshift(DisasContext *s, MemOp ot)
692  {
693      TCGv dshift = tcg_temp_new();
694      tcg_gen_ld32s_tl(dshift, tcg_env, offsetof(CPUX86State, df));
695      tcg_gen_shli_tl(dshift, dshift, ot);
696      return dshift;
697  };
698  
gen_ext_tl(TCGv dst,TCGv src,MemOp size,bool sign)699  static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign)
700  {
701      if (size == MO_TL) {
702          return src;
703      }
704      if (!dst) {
705          dst = tcg_temp_new();
706      }
707      tcg_gen_ext_tl(dst, src, size | (sign ? MO_SIGN : 0));
708      return dst;
709  }
710  
gen_op_j_ecx(DisasContext * s,TCGCond cond,TCGLabel * label1)711  static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1)
712  {
713      TCGv tmp = gen_ext_tl(NULL, cpu_regs[R_ECX], s->aflag, false);
714  
715      tcg_gen_brcondi_tl(cond, tmp, 0, label1);
716  }
717  
gen_op_jz_ecx(DisasContext * s,TCGLabel * label1)718  static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1)
719  {
720      gen_op_j_ecx(s, TCG_COND_EQ, label1);
721  }
722  
gen_op_jnz_ecx(DisasContext * s,TCGLabel * label1)723  static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1)
724  {
725      gen_op_j_ecx(s, TCG_COND_NE, label1);
726  }
727  
gen_helper_in_func(MemOp ot,TCGv v,TCGv_i32 n)728  static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n)
729  {
730      switch (ot) {
731      case MO_8:
732          gen_helper_inb(v, tcg_env, n);
733          break;
734      case MO_16:
735          gen_helper_inw(v, tcg_env, n);
736          break;
737      case MO_32:
738          gen_helper_inl(v, tcg_env, n);
739          break;
740      default:
741          g_assert_not_reached();
742      }
743  }
744  
gen_helper_out_func(MemOp ot,TCGv_i32 v,TCGv_i32 n)745  static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
746  {
747      switch (ot) {
748      case MO_8:
749          gen_helper_outb(tcg_env, v, n);
750          break;
751      case MO_16:
752          gen_helper_outw(tcg_env, v, n);
753          break;
754      case MO_32:
755          gen_helper_outl(tcg_env, v, n);
756          break;
757      default:
758          g_assert_not_reached();
759      }
760  }
761  
762  /*
763   * Validate that access to [port, port + 1<<ot) is allowed.
764   * Raise #GP, or VMM exit if not.
765   */
gen_check_io(DisasContext * s,MemOp ot,TCGv_i32 port,uint32_t svm_flags)766  static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
767                           uint32_t svm_flags)
768  {
769  #ifdef CONFIG_USER_ONLY
770      /*
771       * We do not implement the ioperm(2) syscall, so the TSS check
772       * will always fail.
773       */
774      gen_exception_gpf(s);
775      return false;
776  #else
777      if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
778          gen_helper_check_io(tcg_env, port, tcg_constant_i32(1 << ot));
779      }
780      if (GUEST(s)) {
781          gen_update_cc_op(s);
782          gen_update_eip_cur(s);
783          if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
784              svm_flags |= SVM_IOIO_REP_MASK;
785          }
786          svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot);
787          gen_helper_svm_check_io(tcg_env, port,
788                                  tcg_constant_i32(svm_flags),
789                                  cur_insn_len_i32(s));
790      }
791      return true;
792  #endif
793  }
794  
gen_movs(DisasContext * s,MemOp ot)795  static void gen_movs(DisasContext *s, MemOp ot)
796  {
797      TCGv dshift;
798  
799      gen_string_movl_A0_ESI(s);
800      gen_op_ld_v(s, ot, s->T0, s->A0);
801      gen_string_movl_A0_EDI(s);
802      gen_op_st_v(s, ot, s->T0, s->A0);
803  
804      dshift = gen_compute_Dshift(s, ot);
805      gen_op_add_reg(s, s->aflag, R_ESI, dshift);
806      gen_op_add_reg(s, s->aflag, R_EDI, dshift);
807  }
808  
809  /* compute all eflags to reg */
gen_mov_eflags(DisasContext * s,TCGv reg)810  static void gen_mov_eflags(DisasContext *s, TCGv reg)
811  {
812      TCGv dst, src1, src2;
813      TCGv_i32 cc_op;
814      int live, dead;
815  
816      if (s->cc_op == CC_OP_EFLAGS) {
817          tcg_gen_mov_tl(reg, cpu_cc_src);
818          return;
819      }
820  
821      dst = cpu_cc_dst;
822      src1 = cpu_cc_src;
823      src2 = cpu_cc_src2;
824  
825      /* Take care to not read values that are not live.  */
826      live = cc_op_live(s->cc_op) & ~USES_CC_SRCT;
827      dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
828      if (dead) {
829          TCGv zero = tcg_constant_tl(0);
830          if (dead & USES_CC_DST) {
831              dst = zero;
832          }
833          if (dead & USES_CC_SRC) {
834              src1 = zero;
835          }
836          if (dead & USES_CC_SRC2) {
837              src2 = zero;
838          }
839      }
840  
841      if (s->cc_op != CC_OP_DYNAMIC) {
842          cc_op = tcg_constant_i32(s->cc_op);
843      } else {
844          cc_op = cpu_cc_op;
845      }
846      gen_helper_cc_compute_all(reg, dst, src1, src2, cc_op);
847  }
848  
849  /* compute all eflags to cc_src */
gen_compute_eflags(DisasContext * s)850  static void gen_compute_eflags(DisasContext *s)
851  {
852      gen_mov_eflags(s, cpu_cc_src);
853      set_cc_op(s, CC_OP_EFLAGS);
854  }
855  
856  typedef struct CCPrepare {
857      TCGCond cond;
858      TCGv reg;
859      TCGv reg2;
860      target_ulong imm;
861      bool use_reg2;
862      bool no_setcond;
863  } CCPrepare;
864  
gen_prepare_sign_nz(TCGv src,MemOp size)865  static CCPrepare gen_prepare_sign_nz(TCGv src, MemOp size)
866  {
867      if (size == MO_TL) {
868          return (CCPrepare) { .cond = TCG_COND_LT, .reg = src };
869      } else {
870          return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = src,
871                               .imm = 1ull << ((8 << size) - 1) };
872      }
873  }
874  
gen_prepare_val_nz(TCGv src,MemOp size,bool eqz)875  static CCPrepare gen_prepare_val_nz(TCGv src, MemOp size, bool eqz)
876  {
877      if (size == MO_TL) {
878          return (CCPrepare) { .cond = eqz ? TCG_COND_EQ : TCG_COND_NE,
879                               .reg = src };
880      } else {
881          return (CCPrepare) { .cond = eqz ? TCG_COND_TSTEQ : TCG_COND_TSTNE,
882                               .imm = MAKE_64BIT_MASK(0, 8 << size),
883                               .reg = src };
884      }
885  }
886  
887  /* compute eflags.C, trying to store it in reg if not NULL */
gen_prepare_eflags_c(DisasContext * s,TCGv reg)888  static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
889  {
890      MemOp size;
891  
892      switch (s->cc_op) {
893      case CC_OP_SUBB ... CC_OP_SUBQ:
894          /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
895          size = s->cc_op - CC_OP_SUBB;
896          tcg_gen_ext_tl(s->cc_srcT, s->cc_srcT, size);
897          tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size);
898          return (CCPrepare) { .cond = TCG_COND_LTU, .reg = s->cc_srcT,
899                               .reg2 = cpu_cc_src, .use_reg2 = true };
900  
901      case CC_OP_ADDB ... CC_OP_ADDQ:
902          /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
903          size = cc_op_size(s->cc_op);
904          tcg_gen_ext_tl(cpu_cc_dst, cpu_cc_dst, size);
905          tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size);
906          return (CCPrepare) { .cond = TCG_COND_LTU, .reg = cpu_cc_dst,
907                               .reg2 = cpu_cc_src, .use_reg2 = true };
908  
909      case CC_OP_LOGICB ... CC_OP_LOGICQ:
910      case CC_OP_POPCNT:
911          return (CCPrepare) { .cond = TCG_COND_NEVER };
912  
913      case CC_OP_INCB ... CC_OP_INCQ:
914      case CC_OP_DECB ... CC_OP_DECQ:
915          return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
916                               .no_setcond = true };
917  
918      case CC_OP_SHLB ... CC_OP_SHLQ:
919          /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
920          size = cc_op_size(s->cc_op);
921          return gen_prepare_sign_nz(cpu_cc_src, size);
922  
923      case CC_OP_MULB ... CC_OP_MULQ:
924          return (CCPrepare) { .cond = TCG_COND_NE,
925                               .reg = cpu_cc_src };
926  
927      case CC_OP_BMILGB ... CC_OP_BMILGQ:
928          size = cc_op_size(s->cc_op);
929          return gen_prepare_val_nz(cpu_cc_src, size, true);
930  
931      case CC_OP_BLSIB ... CC_OP_BLSIQ:
932          size = cc_op_size(s->cc_op);
933          return gen_prepare_val_nz(cpu_cc_src, size, false);
934  
935      case CC_OP_ADCX:
936      case CC_OP_ADCOX:
937          return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
938                               .no_setcond = true };
939  
940      case CC_OP_EFLAGS:
941      case CC_OP_SARB ... CC_OP_SARQ:
942          /* CC_SRC & 1 */
943          return (CCPrepare) { .cond = TCG_COND_TSTNE,
944                               .reg = cpu_cc_src, .imm = CC_C };
945  
946      default:
947         /* The need to compute only C from CC_OP_DYNAMIC is important
948            in efficiently implementing e.g. INC at the start of a TB.  */
949         gen_update_cc_op(s);
950         if (!reg) {
951             reg = tcg_temp_new();
952         }
953         gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
954                                 cpu_cc_src2, cpu_cc_op);
955         return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
956                              .no_setcond = true };
957      }
958  }
959  
960  /* compute eflags.P, trying to store it in reg if not NULL */
gen_prepare_eflags_p(DisasContext * s,TCGv reg)961  static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
962  {
963      gen_compute_eflags(s);
964      return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
965                           .imm = CC_P };
966  }
967  
968  /* compute eflags.S, trying to store it in reg if not NULL */
gen_prepare_eflags_s(DisasContext * s,TCGv reg)969  static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
970  {
971      switch (s->cc_op) {
972      case CC_OP_DYNAMIC:
973          gen_compute_eflags(s);
974          /* FALLTHRU */
975      case CC_OP_EFLAGS:
976      case CC_OP_ADCX:
977      case CC_OP_ADOX:
978      case CC_OP_ADCOX:
979          return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
980                               .imm = CC_S };
981      case CC_OP_POPCNT:
982          return (CCPrepare) { .cond = TCG_COND_NEVER };
983      default:
984          return gen_prepare_sign_nz(cpu_cc_dst, cc_op_size(s->cc_op));
985      }
986  }
987  
988  /* compute eflags.O, trying to store it in reg if not NULL */
gen_prepare_eflags_o(DisasContext * s,TCGv reg)989  static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
990  {
991      switch (s->cc_op) {
992      case CC_OP_ADOX:
993      case CC_OP_ADCOX:
994          return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
995                               .no_setcond = true };
996      case CC_OP_LOGICB ... CC_OP_LOGICQ:
997      case CC_OP_POPCNT:
998          return (CCPrepare) { .cond = TCG_COND_NEVER };
999      case CC_OP_MULB ... CC_OP_MULQ:
1000          return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src };
1001      default:
1002          gen_compute_eflags(s);
1003          return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
1004                               .imm = CC_O };
1005      }
1006  }
1007  
1008  /* compute eflags.Z, trying to store it in reg if not NULL */
gen_prepare_eflags_z(DisasContext * s,TCGv reg)1009  static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
1010  {
1011      switch (s->cc_op) {
1012      case CC_OP_EFLAGS:
1013      case CC_OP_ADCX:
1014      case CC_OP_ADOX:
1015      case CC_OP_ADCOX:
1016          return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
1017                               .imm = CC_Z };
1018      case CC_OP_DYNAMIC:
1019          gen_update_cc_op(s);
1020          if (!reg) {
1021              reg = tcg_temp_new();
1022          }
1023          gen_helper_cc_compute_nz(reg, cpu_cc_dst, cpu_cc_src, cpu_cc_op);
1024          return (CCPrepare) { .cond = TCG_COND_EQ, .reg = reg, .imm = 0 };
1025      case CC_OP_POPCNT:
1026          return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_dst };
1027      default:
1028          {
1029              MemOp size = cc_op_size(s->cc_op);
1030              return gen_prepare_val_nz(cpu_cc_dst, size, true);
1031          }
1032      }
1033  }
1034  
1035  /* return how to compute jump opcode 'b'.  'reg' can be clobbered
1036   * if needed; it may be used for CCPrepare.reg if that will
1037   * provide more freedom in the translation of a subsequent setcond. */
gen_prepare_cc(DisasContext * s,int b,TCGv reg)1038  static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1039  {
1040      int inv, jcc_op, cond;
1041      MemOp size;
1042      CCPrepare cc;
1043  
1044      inv = b & 1;
1045      jcc_op = (b >> 1) & 7;
1046  
1047      switch (s->cc_op) {
1048      case CC_OP_SUBB ... CC_OP_SUBQ:
1049          /* We optimize relational operators for the cmp/jcc case.  */
1050          size = cc_op_size(s->cc_op);
1051          switch (jcc_op) {
1052          case JCC_BE:
1053              tcg_gen_ext_tl(s->cc_srcT, s->cc_srcT, size);
1054              tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size);
1055              cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->cc_srcT,
1056                                 .reg2 = cpu_cc_src, .use_reg2 = true };
1057              break;
1058          case JCC_L:
1059              cond = TCG_COND_LT;
1060              goto fast_jcc_l;
1061          case JCC_LE:
1062              cond = TCG_COND_LE;
1063          fast_jcc_l:
1064              tcg_gen_ext_tl(s->cc_srcT, s->cc_srcT, size | MO_SIGN);
1065              tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size | MO_SIGN);
1066              cc = (CCPrepare) { .cond = cond, .reg = s->cc_srcT,
1067                                 .reg2 = cpu_cc_src, .use_reg2 = true };
1068              break;
1069  
1070          default:
1071              goto slow_jcc;
1072          }
1073          break;
1074  
1075      case CC_OP_LOGICB ... CC_OP_LOGICQ:
1076          /* Mostly used for test+jump */
1077          size = s->cc_op - CC_OP_LOGICB;
1078          switch (jcc_op) {
1079          case JCC_BE:
1080              /* CF = 0, becomes jz/je */
1081              jcc_op = JCC_Z;
1082              goto slow_jcc;
1083          case JCC_L:
1084              /* OF = 0, becomes js/jns */
1085              jcc_op = JCC_S;
1086              goto slow_jcc;
1087          case JCC_LE:
1088              /* SF or ZF, becomes signed <= 0 */
1089              tcg_gen_ext_tl(cpu_cc_dst, cpu_cc_dst, size | MO_SIGN);
1090              cc = (CCPrepare) { .cond = TCG_COND_LE, .reg = cpu_cc_dst };
1091              break;
1092          default:
1093              goto slow_jcc;
1094          }
1095          break;
1096  
1097      default:
1098      slow_jcc:
1099          /* This actually generates good code for JC, JZ and JS.  */
1100          switch (jcc_op) {
1101          case JCC_O:
1102              cc = gen_prepare_eflags_o(s, reg);
1103              break;
1104          case JCC_B:
1105              cc = gen_prepare_eflags_c(s, reg);
1106              break;
1107          case JCC_Z:
1108              cc = gen_prepare_eflags_z(s, reg);
1109              break;
1110          case JCC_BE:
1111              gen_compute_eflags(s);
1112              cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
1113                                 .imm = CC_Z | CC_C };
1114              break;
1115          case JCC_S:
1116              cc = gen_prepare_eflags_s(s, reg);
1117              break;
1118          case JCC_P:
1119              cc = gen_prepare_eflags_p(s, reg);
1120              break;
1121          case JCC_L:
1122              gen_compute_eflags(s);
1123              if (!reg || reg == cpu_cc_src) {
1124                  reg = tcg_temp_new();
1125              }
1126              tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S);
1127              cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg,
1128                                 .imm = CC_O };
1129              break;
1130          default:
1131          case JCC_LE:
1132              gen_compute_eflags(s);
1133              if (!reg || reg == cpu_cc_src) {
1134                  reg = tcg_temp_new();
1135              }
1136              tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S);
1137              cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg,
1138                                 .imm = CC_O | CC_Z };
1139              break;
1140          }
1141          break;
1142      }
1143  
1144      if (inv) {
1145          cc.cond = tcg_invert_cond(cc.cond);
1146      }
1147      return cc;
1148  }
1149  
gen_setcc1(DisasContext * s,int b,TCGv reg)1150  static void gen_setcc1(DisasContext *s, int b, TCGv reg)
1151  {
1152      CCPrepare cc = gen_prepare_cc(s, b, reg);
1153  
1154      if (cc.no_setcond) {
1155          if (cc.cond == TCG_COND_EQ) {
1156              tcg_gen_xori_tl(reg, cc.reg, 1);
1157          } else {
1158              tcg_gen_mov_tl(reg, cc.reg);
1159          }
1160          return;
1161      }
1162  
1163      if (cc.use_reg2) {
1164          tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1165      } else {
1166          tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1167      }
1168  }
1169  
gen_compute_eflags_c(DisasContext * s,TCGv reg)1170  static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1171  {
1172      gen_setcc1(s, JCC_B << 1, reg);
1173  }
1174  
1175  /* generate a conditional jump to label 'l1' according to jump opcode
1176     value 'b'. In the fast case, T0 is guaranteed not to be used. */
gen_jcc1_noeob(DisasContext * s,int b,TCGLabel * l1)1177  static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1178  {
1179      CCPrepare cc = gen_prepare_cc(s, b, NULL);
1180  
1181      if (cc.use_reg2) {
1182          tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1183      } else {
1184          tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1185      }
1186  }
1187  
1188  /* Generate a conditional jump to label 'l1' according to jump opcode
1189     value 'b'. In the fast case, T0 is guaranteed not to be used.
1190     One or both of the branches will call gen_jmp_rel, so ensure
1191     cc_op is clean.  */
gen_jcc1(DisasContext * s,int b,TCGLabel * l1)1192  static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1193  {
1194      CCPrepare cc = gen_prepare_cc(s, b, NULL);
1195  
1196      /*
1197       * Note that this must be _after_ gen_prepare_cc, because it
1198       * can change the cc_op from CC_OP_DYNAMIC to CC_OP_EFLAGS!
1199       */
1200      gen_update_cc_op(s);
1201      if (cc.use_reg2) {
1202          tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1203      } else {
1204          tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1205      }
1206  }
1207  
1208  /* XXX: does not work with gdbstub "ice" single step - not a
1209     serious problem.  The caller can jump to the returned label
1210     to stop the REP but, if the flags have changed, it has to call
1211     gen_update_cc_op before doing so.  */
gen_jz_ecx_string(DisasContext * s)1212  static TCGLabel *gen_jz_ecx_string(DisasContext *s)
1213  {
1214      TCGLabel *l1 = gen_new_label();
1215      TCGLabel *l2 = gen_new_label();
1216  
1217      gen_update_cc_op(s);
1218      gen_op_jnz_ecx(s, l1);
1219      gen_set_label(l2);
1220      gen_jmp_rel_csize(s, 0, 1);
1221      gen_set_label(l1);
1222      return l2;
1223  }
1224  
gen_stos(DisasContext * s,MemOp ot)1225  static void gen_stos(DisasContext *s, MemOp ot)
1226  {
1227      gen_string_movl_A0_EDI(s);
1228      gen_op_st_v(s, ot, s->T0, s->A0);
1229      gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot));
1230  }
1231  
gen_lods(DisasContext * s,MemOp ot)1232  static void gen_lods(DisasContext *s, MemOp ot)
1233  {
1234      gen_string_movl_A0_ESI(s);
1235      gen_op_ld_v(s, ot, s->T0, s->A0);
1236      gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
1237      gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot));
1238  }
1239  
gen_scas(DisasContext * s,MemOp ot)1240  static void gen_scas(DisasContext *s, MemOp ot)
1241  {
1242      gen_string_movl_A0_EDI(s);
1243      gen_op_ld_v(s, ot, s->T1, s->A0);
1244      tcg_gen_mov_tl(cpu_cc_src, s->T1);
1245      tcg_gen_mov_tl(s->cc_srcT, s->T0);
1246      tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1);
1247      set_cc_op(s, CC_OP_SUBB + ot);
1248  
1249      gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot));
1250  }
1251  
gen_cmps(DisasContext * s,MemOp ot)1252  static void gen_cmps(DisasContext *s, MemOp ot)
1253  {
1254      TCGv dshift;
1255  
1256      gen_string_movl_A0_EDI(s);
1257      gen_op_ld_v(s, ot, s->T1, s->A0);
1258      gen_string_movl_A0_ESI(s);
1259      gen_op_ld_v(s, ot, s->T0, s->A0);
1260      tcg_gen_mov_tl(cpu_cc_src, s->T1);
1261      tcg_gen_mov_tl(s->cc_srcT, s->T0);
1262      tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1);
1263      set_cc_op(s, CC_OP_SUBB + ot);
1264  
1265      dshift = gen_compute_Dshift(s, ot);
1266      gen_op_add_reg(s, s->aflag, R_ESI, dshift);
1267      gen_op_add_reg(s, s->aflag, R_EDI, dshift);
1268  }
1269  
gen_bpt_io(DisasContext * s,TCGv_i32 t_port,int ot)1270  static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1271  {
1272      if (s->flags & HF_IOBPT_MASK) {
1273  #ifdef CONFIG_USER_ONLY
1274          /* user-mode cpu should not be in IOBPT mode */
1275          g_assert_not_reached();
1276  #else
1277          TCGv_i32 t_size = tcg_constant_i32(1 << ot);
1278          TCGv t_next = eip_next_tl(s);
1279          gen_helper_bpt_io(tcg_env, t_port, t_size, t_next);
1280  #endif /* CONFIG_USER_ONLY */
1281      }
1282  }
1283  
gen_ins(DisasContext * s,MemOp ot)1284  static void gen_ins(DisasContext *s, MemOp ot)
1285  {
1286      gen_string_movl_A0_EDI(s);
1287      /* Note: we must do this dummy write first to be restartable in
1288         case of page fault. */
1289      tcg_gen_movi_tl(s->T0, 0);
1290      gen_op_st_v(s, ot, s->T0, s->A0);
1291      tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1292      tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1293      gen_helper_in_func(ot, s->T0, s->tmp2_i32);
1294      gen_op_st_v(s, ot, s->T0, s->A0);
1295      gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot));
1296      gen_bpt_io(s, s->tmp2_i32, ot);
1297  }
1298  
gen_outs(DisasContext * s,MemOp ot)1299  static void gen_outs(DisasContext *s, MemOp ot)
1300  {
1301      gen_string_movl_A0_ESI(s);
1302      gen_op_ld_v(s, ot, s->T0, s->A0);
1303  
1304      tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1305      tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1306      tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0);
1307      gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
1308      gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot));
1309      gen_bpt_io(s, s->tmp2_i32, ot);
1310  }
1311  
1312  /* Generate jumps to current or next instruction */
gen_repz(DisasContext * s,MemOp ot,void (* fn)(DisasContext * s,MemOp ot))1313  static void gen_repz(DisasContext *s, MemOp ot,
1314                       void (*fn)(DisasContext *s, MemOp ot))
1315  {
1316      TCGLabel *l2;
1317      l2 = gen_jz_ecx_string(s);
1318      fn(s, ot);
1319      gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1320      /*
1321       * A loop would cause two single step exceptions if ECX = 1
1322       * before rep string_insn
1323       */
1324      if (s->repz_opt) {
1325          gen_op_jz_ecx(s, l2);
1326      }
1327      gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1328  }
1329  
gen_repz_nz(DisasContext * s,MemOp ot,void (* fn)(DisasContext * s,MemOp ot))1330  static void gen_repz_nz(DisasContext *s, MemOp ot,
1331                          void (*fn)(DisasContext *s, MemOp ot))
1332  {
1333      TCGLabel *l2;
1334      int nz = (s->prefix & PREFIX_REPNZ) ? 1 : 0;
1335  
1336      l2 = gen_jz_ecx_string(s);
1337      fn(s, ot);
1338      gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1339      gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);
1340      if (s->repz_opt) {
1341          gen_op_jz_ecx(s, l2);
1342      }
1343      /*
1344       * Only one iteration is done at a time, so the translation
1345       * block ends unconditionally after this instruction and there
1346       * is no control flow junction - no need to set CC_OP_DYNAMIC.
1347       */
1348      gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1349  }
1350  
gen_helper_fp_arith_ST0_FT0(int op)1351  static void gen_helper_fp_arith_ST0_FT0(int op)
1352  {
1353      switch (op) {
1354      case 0:
1355          gen_helper_fadd_ST0_FT0(tcg_env);
1356          break;
1357      case 1:
1358          gen_helper_fmul_ST0_FT0(tcg_env);
1359          break;
1360      case 2:
1361          gen_helper_fcom_ST0_FT0(tcg_env);
1362          break;
1363      case 3:
1364          gen_helper_fcom_ST0_FT0(tcg_env);
1365          break;
1366      case 4:
1367          gen_helper_fsub_ST0_FT0(tcg_env);
1368          break;
1369      case 5:
1370          gen_helper_fsubr_ST0_FT0(tcg_env);
1371          break;
1372      case 6:
1373          gen_helper_fdiv_ST0_FT0(tcg_env);
1374          break;
1375      case 7:
1376          gen_helper_fdivr_ST0_FT0(tcg_env);
1377          break;
1378      }
1379  }
1380  
1381  /* NOTE the exception in "r" op ordering */
gen_helper_fp_arith_STN_ST0(int op,int opreg)1382  static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1383  {
1384      TCGv_i32 tmp = tcg_constant_i32(opreg);
1385      switch (op) {
1386      case 0:
1387          gen_helper_fadd_STN_ST0(tcg_env, tmp);
1388          break;
1389      case 1:
1390          gen_helper_fmul_STN_ST0(tcg_env, tmp);
1391          break;
1392      case 4:
1393          gen_helper_fsubr_STN_ST0(tcg_env, tmp);
1394          break;
1395      case 5:
1396          gen_helper_fsub_STN_ST0(tcg_env, tmp);
1397          break;
1398      case 6:
1399          gen_helper_fdivr_STN_ST0(tcg_env, tmp);
1400          break;
1401      case 7:
1402          gen_helper_fdiv_STN_ST0(tcg_env, tmp);
1403          break;
1404      }
1405  }
1406  
gen_exception(DisasContext * s,int trapno)1407  static void gen_exception(DisasContext *s, int trapno)
1408  {
1409      gen_update_cc_op(s);
1410      gen_update_eip_cur(s);
1411      gen_helper_raise_exception(tcg_env, tcg_constant_i32(trapno));
1412      s->base.is_jmp = DISAS_NORETURN;
1413  }
1414  
1415  /* Generate #UD for the current instruction.  The assumption here is that
1416     the instruction is known, but it isn't allowed in the current cpu mode.  */
gen_illegal_opcode(DisasContext * s)1417  static void gen_illegal_opcode(DisasContext *s)
1418  {
1419      gen_exception(s, EXCP06_ILLOP);
1420  }
1421  
1422  /* Generate #GP for the current instruction. */
gen_exception_gpf(DisasContext * s)1423  static void gen_exception_gpf(DisasContext *s)
1424  {
1425      gen_exception(s, EXCP0D_GPF);
1426  }
1427  
1428  /* Check for cpl == 0; if not, raise #GP and return false. */
check_cpl0(DisasContext * s)1429  static bool check_cpl0(DisasContext *s)
1430  {
1431      if (CPL(s) == 0) {
1432          return true;
1433      }
1434      gen_exception_gpf(s);
1435      return false;
1436  }
1437  
1438  /* XXX: add faster immediate case */
gen_shiftd_rm_T1(DisasContext * s,MemOp ot,bool is_right,TCGv count)1439  static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot,
1440                               bool is_right, TCGv count)
1441  {
1442      target_ulong mask = (ot == MO_64 ? 63 : 31);
1443  
1444      switch (ot) {
1445      case MO_16:
1446          /* Note: we implement the Intel behaviour for shift count > 16.
1447             This means "shrdw C, B, A" shifts A:B:A >> C.  Build the B:A
1448             portion by constructing it as a 32-bit value.  */
1449          if (is_right) {
1450              tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16);
1451              tcg_gen_mov_tl(s->T1, s->T0);
1452              tcg_gen_mov_tl(s->T0, s->tmp0);
1453          } else {
1454              tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16);
1455          }
1456          /*
1457           * If TARGET_X86_64 defined then fall through into MO_32 case,
1458           * otherwise fall through default case.
1459           */
1460      case MO_32:
1461  #ifdef TARGET_X86_64
1462          /* Concatenate the two 32-bit values and use a 64-bit shift.  */
1463          tcg_gen_subi_tl(s->tmp0, count, 1);
1464          if (is_right) {
1465              tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1);
1466              tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0);
1467              tcg_gen_shr_i64(s->T0, s->T0, count);
1468          } else {
1469              tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0);
1470              tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0);
1471              tcg_gen_shl_i64(s->T0, s->T0, count);
1472              tcg_gen_shri_i64(s->tmp0, s->tmp0, 32);
1473              tcg_gen_shri_i64(s->T0, s->T0, 32);
1474          }
1475          break;
1476  #endif
1477      default:
1478          tcg_gen_subi_tl(s->tmp0, count, 1);
1479          if (is_right) {
1480              tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0);
1481  
1482              tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
1483              tcg_gen_shr_tl(s->T0, s->T0, count);
1484              tcg_gen_shl_tl(s->T1, s->T1, s->tmp4);
1485          } else {
1486              tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0);
1487              if (ot == MO_16) {
1488                  /* Only needed if count > 16, for Intel behaviour.  */
1489                  tcg_gen_subfi_tl(s->tmp4, 33, count);
1490                  tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4);
1491                  tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4);
1492              }
1493  
1494              tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
1495              tcg_gen_shl_tl(s->T0, s->T0, count);
1496              tcg_gen_shr_tl(s->T1, s->T1, s->tmp4);
1497          }
1498          tcg_gen_movi_tl(s->tmp4, 0);
1499          tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4,
1500                             s->tmp4, s->T1);
1501          tcg_gen_or_tl(s->T0, s->T0, s->T1);
1502          break;
1503      }
1504  }
1505  
1506  #define X86_MAX_INSN_LENGTH 15
1507  
advance_pc(CPUX86State * env,DisasContext * s,int num_bytes)1508  static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
1509  {
1510      uint64_t pc = s->pc;
1511  
1512      /* This is a subsequent insn that crosses a page boundary.  */
1513      if (s->base.num_insns > 1 &&
1514          !is_same_page(&s->base, s->pc + num_bytes - 1)) {
1515          siglongjmp(s->jmpbuf, 2);
1516      }
1517  
1518      s->pc += num_bytes;
1519      if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) {
1520          /* If the instruction's 16th byte is on a different page than the 1st, a
1521           * page fault on the second page wins over the general protection fault
1522           * caused by the instruction being too long.
1523           * This can happen even if the operand is only one byte long!
1524           */
1525          if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) {
1526              (void)translator_ldub(env, &s->base,
1527                                    (s->pc - 1) & TARGET_PAGE_MASK);
1528          }
1529          siglongjmp(s->jmpbuf, 1);
1530      }
1531  
1532      return pc;
1533  }
1534  
x86_ldub_code(CPUX86State * env,DisasContext * s)1535  static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
1536  {
1537      return translator_ldub(env, &s->base, advance_pc(env, s, 1));
1538  }
1539  
x86_lduw_code(CPUX86State * env,DisasContext * s)1540  static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
1541  {
1542      return translator_lduw(env, &s->base, advance_pc(env, s, 2));
1543  }
1544  
x86_ldl_code(CPUX86State * env,DisasContext * s)1545  static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
1546  {
1547      return translator_ldl(env, &s->base, advance_pc(env, s, 4));
1548  }
1549  
1550  #ifdef TARGET_X86_64
x86_ldq_code(CPUX86State * env,DisasContext * s)1551  static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
1552  {
1553      return translator_ldq(env, &s->base, advance_pc(env, s, 8));
1554  }
1555  #endif
1556  
1557  /* Decompose an address.  */
1558  
gen_lea_modrm_0(CPUX86State * env,DisasContext * s,int modrm,bool is_vsib)1559  static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
1560                                      int modrm, bool is_vsib)
1561  {
1562      int def_seg, base, index, scale, mod, rm;
1563      target_long disp;
1564      bool havesib;
1565  
1566      def_seg = R_DS;
1567      index = -1;
1568      scale = 0;
1569      disp = 0;
1570  
1571      mod = (modrm >> 6) & 3;
1572      rm = modrm & 7;
1573      base = rm | REX_B(s);
1574  
1575      if (mod == 3) {
1576          /* Normally filtered out earlier, but including this path
1577             simplifies multi-byte nop, as well as bndcl, bndcu, bndcn.  */
1578          goto done;
1579      }
1580  
1581      switch (s->aflag) {
1582      case MO_64:
1583      case MO_32:
1584          havesib = 0;
1585          if (rm == 4) {
1586              int code = x86_ldub_code(env, s);
1587              scale = (code >> 6) & 3;
1588              index = ((code >> 3) & 7) | REX_X(s);
1589              if (index == 4 && !is_vsib) {
1590                  index = -1;  /* no index */
1591              }
1592              base = (code & 7) | REX_B(s);
1593              havesib = 1;
1594          }
1595  
1596          switch (mod) {
1597          case 0:
1598              if ((base & 7) == 5) {
1599                  base = -1;
1600                  disp = (int32_t)x86_ldl_code(env, s);
1601                  if (CODE64(s) && !havesib) {
1602                      base = -2;
1603                      disp += s->pc + s->rip_offset;
1604                  }
1605              }
1606              break;
1607          case 1:
1608              disp = (int8_t)x86_ldub_code(env, s);
1609              break;
1610          default:
1611          case 2:
1612              disp = (int32_t)x86_ldl_code(env, s);
1613              break;
1614          }
1615  
1616          /* For correct popl handling with esp.  */
1617          if (base == R_ESP && s->popl_esp_hack) {
1618              disp += s->popl_esp_hack;
1619          }
1620          if (base == R_EBP || base == R_ESP) {
1621              def_seg = R_SS;
1622          }
1623          break;
1624  
1625      case MO_16:
1626          if (mod == 0) {
1627              if (rm == 6) {
1628                  base = -1;
1629                  disp = x86_lduw_code(env, s);
1630                  break;
1631              }
1632          } else if (mod == 1) {
1633              disp = (int8_t)x86_ldub_code(env, s);
1634          } else {
1635              disp = (int16_t)x86_lduw_code(env, s);
1636          }
1637  
1638          switch (rm) {
1639          case 0:
1640              base = R_EBX;
1641              index = R_ESI;
1642              break;
1643          case 1:
1644              base = R_EBX;
1645              index = R_EDI;
1646              break;
1647          case 2:
1648              base = R_EBP;
1649              index = R_ESI;
1650              def_seg = R_SS;
1651              break;
1652          case 3:
1653              base = R_EBP;
1654              index = R_EDI;
1655              def_seg = R_SS;
1656              break;
1657          case 4:
1658              base = R_ESI;
1659              break;
1660          case 5:
1661              base = R_EDI;
1662              break;
1663          case 6:
1664              base = R_EBP;
1665              def_seg = R_SS;
1666              break;
1667          default:
1668          case 7:
1669              base = R_EBX;
1670              break;
1671          }
1672          break;
1673  
1674      default:
1675          g_assert_not_reached();
1676      }
1677  
1678   done:
1679      return (AddressParts){ def_seg, base, index, scale, disp };
1680  }
1681  
1682  /* Compute the address, with a minimum number of TCG ops.  */
gen_lea_modrm_1(DisasContext * s,AddressParts a,bool is_vsib)1683  static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib)
1684  {
1685      TCGv ea = NULL;
1686  
1687      if (a.index >= 0 && !is_vsib) {
1688          if (a.scale == 0) {
1689              ea = cpu_regs[a.index];
1690          } else {
1691              tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale);
1692              ea = s->A0;
1693          }
1694          if (a.base >= 0) {
1695              tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]);
1696              ea = s->A0;
1697          }
1698      } else if (a.base >= 0) {
1699          ea = cpu_regs[a.base];
1700      }
1701      if (!ea) {
1702          if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) {
1703              /* With cpu_eip ~= pc_save, the expression is pc-relative. */
1704              tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save);
1705          } else {
1706              tcg_gen_movi_tl(s->A0, a.disp);
1707          }
1708          ea = s->A0;
1709      } else if (a.disp != 0) {
1710          tcg_gen_addi_tl(s->A0, ea, a.disp);
1711          ea = s->A0;
1712      }
1713  
1714      return ea;
1715  }
1716  
1717  /* Used for BNDCL, BNDCU, BNDCN.  */
gen_bndck(DisasContext * s,X86DecodedInsn * decode,TCGCond cond,TCGv_i64 bndv)1718  static void gen_bndck(DisasContext *s, X86DecodedInsn *decode,
1719                        TCGCond cond, TCGv_i64 bndv)
1720  {
1721      TCGv ea = gen_lea_modrm_1(s, decode->mem, false);
1722  
1723      tcg_gen_extu_tl_i64(s->tmp1_i64, ea);
1724      if (!CODE64(s)) {
1725          tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64);
1726      }
1727      tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv);
1728      tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64);
1729      gen_helper_bndck(tcg_env, s->tmp2_i32);
1730  }
1731  
1732  /* generate modrm load of memory or register. */
gen_ld_modrm(DisasContext * s,X86DecodedInsn * decode,MemOp ot)1733  static void gen_ld_modrm(DisasContext *s, X86DecodedInsn *decode, MemOp ot)
1734  {
1735      int modrm = s->modrm;
1736      int mod, rm;
1737  
1738      mod = (modrm >> 6) & 3;
1739      rm = (modrm & 7) | REX_B(s);
1740      if (mod == 3) {
1741          gen_op_mov_v_reg(s, ot, s->T0, rm);
1742      } else {
1743          gen_lea_modrm(s, decode);
1744          gen_op_ld_v(s, ot, s->T0, s->A0);
1745      }
1746  }
1747  
1748  /* generate modrm store of memory or register. */
gen_st_modrm(DisasContext * s,X86DecodedInsn * decode,MemOp ot)1749  static void gen_st_modrm(DisasContext *s, X86DecodedInsn *decode, MemOp ot)
1750  {
1751      int modrm = s->modrm;
1752      int mod, rm;
1753  
1754      mod = (modrm >> 6) & 3;
1755      rm = (modrm & 7) | REX_B(s);
1756      if (mod == 3) {
1757          gen_op_mov_reg_v(s, ot, rm, s->T0);
1758      } else {
1759          gen_lea_modrm(s, decode);
1760          gen_op_st_v(s, ot, s->T0, s->A0);
1761      }
1762  }
1763  
insn_get_addr(CPUX86State * env,DisasContext * s,MemOp ot)1764  static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot)
1765  {
1766      target_ulong ret;
1767  
1768      switch (ot) {
1769      case MO_8:
1770          ret = x86_ldub_code(env, s);
1771          break;
1772      case MO_16:
1773          ret = x86_lduw_code(env, s);
1774          break;
1775      case MO_32:
1776          ret = x86_ldl_code(env, s);
1777          break;
1778  #ifdef TARGET_X86_64
1779      case MO_64:
1780          ret = x86_ldq_code(env, s);
1781          break;
1782  #endif
1783      default:
1784          g_assert_not_reached();
1785      }
1786      return ret;
1787  }
1788  
insn_get(CPUX86State * env,DisasContext * s,MemOp ot)1789  static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot)
1790  {
1791      uint32_t ret;
1792  
1793      switch (ot) {
1794      case MO_8:
1795          ret = x86_ldub_code(env, s);
1796          break;
1797      case MO_16:
1798          ret = x86_lduw_code(env, s);
1799          break;
1800      case MO_32:
1801  #ifdef TARGET_X86_64
1802      case MO_64:
1803  #endif
1804          ret = x86_ldl_code(env, s);
1805          break;
1806      default:
1807          g_assert_not_reached();
1808      }
1809      return ret;
1810  }
1811  
insn_get_signed(CPUX86State * env,DisasContext * s,MemOp ot)1812  static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot)
1813  {
1814      target_long ret;
1815  
1816      switch (ot) {
1817      case MO_8:
1818          ret = (int8_t) x86_ldub_code(env, s);
1819          break;
1820      case MO_16:
1821          ret = (int16_t) x86_lduw_code(env, s);
1822          break;
1823      case MO_32:
1824          ret = (int32_t) x86_ldl_code(env, s);
1825          break;
1826  #ifdef TARGET_X86_64
1827      case MO_64:
1828          ret = x86_ldq_code(env, s);
1829          break;
1830  #endif
1831      default:
1832          g_assert_not_reached();
1833      }
1834      return ret;
1835  }
1836  
gen_conditional_jump_labels(DisasContext * s,target_long diff,TCGLabel * not_taken,TCGLabel * taken)1837  static void gen_conditional_jump_labels(DisasContext *s, target_long diff,
1838                                          TCGLabel *not_taken, TCGLabel *taken)
1839  {
1840      if (not_taken) {
1841          gen_set_label(not_taken);
1842      }
1843      gen_jmp_rel_csize(s, 0, 1);
1844  
1845      gen_set_label(taken);
1846      gen_jmp_rel(s, s->dflag, diff, 0);
1847  }
1848  
gen_jcc(DisasContext * s,int b,int diff)1849  static void gen_jcc(DisasContext *s, int b, int diff)
1850  {
1851      TCGLabel *l1 = gen_new_label();
1852  
1853      gen_jcc1(s, b, l1);
1854      gen_conditional_jump_labels(s, diff, NULL, l1);
1855  }
1856  
gen_cmovcc1(DisasContext * s,int b,TCGv dest,TCGv src)1857  static void gen_cmovcc1(DisasContext *s, int b, TCGv dest, TCGv src)
1858  {
1859      CCPrepare cc = gen_prepare_cc(s, b, NULL);
1860  
1861      if (!cc.use_reg2) {
1862          cc.reg2 = tcg_constant_tl(cc.imm);
1863      }
1864  
1865      tcg_gen_movcond_tl(cc.cond, dest, cc.reg, cc.reg2, src, dest);
1866  }
1867  
gen_op_movl_seg_real(DisasContext * s,X86Seg seg_reg,TCGv seg)1868  static void gen_op_movl_seg_real(DisasContext *s, X86Seg seg_reg, TCGv seg)
1869  {
1870      TCGv selector = tcg_temp_new();
1871      tcg_gen_ext16u_tl(selector, seg);
1872      tcg_gen_st32_tl(selector, tcg_env,
1873                      offsetof(CPUX86State,segs[seg_reg].selector));
1874      tcg_gen_shli_tl(cpu_seg_base[seg_reg], selector, 4);
1875  }
1876  
1877  /* move SRC to seg_reg and compute if the CPU state may change. Never
1878     call this function with seg_reg == R_CS */
gen_movl_seg(DisasContext * s,X86Seg seg_reg,TCGv src)1879  static void gen_movl_seg(DisasContext *s, X86Seg seg_reg, TCGv src)
1880  {
1881      if (PE(s) && !VM86(s)) {
1882          tcg_gen_trunc_tl_i32(s->tmp2_i32, src);
1883          gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32);
1884          /* abort translation because the addseg value may change or
1885             because ss32 may change. For R_SS, translation must always
1886             stop as a special handling must be done to disable hardware
1887             interrupts for the next instruction */
1888          if (seg_reg == R_SS) {
1889              s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
1890          } else if (CODE32(s) && seg_reg < R_FS) {
1891              s->base.is_jmp = DISAS_EOB_NEXT;
1892          }
1893      } else {
1894          gen_op_movl_seg_real(s, seg_reg, src);
1895          if (seg_reg == R_SS) {
1896              s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
1897          }
1898      }
1899  }
1900  
gen_far_call(DisasContext * s)1901  static void gen_far_call(DisasContext *s)
1902  {
1903      TCGv_i32 new_cs = tcg_temp_new_i32();
1904      tcg_gen_trunc_tl_i32(new_cs, s->T1);
1905      if (PE(s) && !VM86(s)) {
1906          gen_helper_lcall_protected(tcg_env, new_cs, s->T0,
1907                                     tcg_constant_i32(s->dflag - 1),
1908                                     eip_next_tl(s));
1909      } else {
1910          TCGv_i32 new_eip = tcg_temp_new_i32();
1911          tcg_gen_trunc_tl_i32(new_eip, s->T0);
1912          gen_helper_lcall_real(tcg_env, new_cs, new_eip,
1913                                tcg_constant_i32(s->dflag - 1),
1914                                eip_next_i32(s));
1915      }
1916      s->base.is_jmp = DISAS_JUMP;
1917  }
1918  
gen_far_jmp(DisasContext * s)1919  static void gen_far_jmp(DisasContext *s)
1920  {
1921      if (PE(s) && !VM86(s)) {
1922          TCGv_i32 new_cs = tcg_temp_new_i32();
1923          tcg_gen_trunc_tl_i32(new_cs, s->T1);
1924          gen_helper_ljmp_protected(tcg_env, new_cs, s->T0,
1925                                    eip_next_tl(s));
1926      } else {
1927          gen_op_movl_seg_real(s, R_CS, s->T1);
1928          gen_op_jmp_v(s, s->T0);
1929      }
1930      s->base.is_jmp = DISAS_JUMP;
1931  }
1932  
gen_svm_check_intercept(DisasContext * s,uint32_t type)1933  static void gen_svm_check_intercept(DisasContext *s, uint32_t type)
1934  {
1935      /* no SVM activated; fast case */
1936      if (likely(!GUEST(s))) {
1937          return;
1938      }
1939      gen_helper_svm_check_intercept(tcg_env, tcg_constant_i32(type));
1940  }
1941  
gen_stack_update(DisasContext * s,int addend)1942  static inline void gen_stack_update(DisasContext *s, int addend)
1943  {
1944      gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend);
1945  }
1946  
gen_lea_ss_ofs(DisasContext * s,TCGv dest,TCGv src,target_ulong offset)1947  static void gen_lea_ss_ofs(DisasContext *s, TCGv dest, TCGv src, target_ulong offset)
1948  {
1949      if (offset) {
1950          tcg_gen_addi_tl(dest, src, offset);
1951          src = dest;
1952      }
1953      gen_lea_v_seg_dest(s, mo_stacksize(s), dest, src, R_SS, -1);
1954  }
1955  
1956  /* Generate a push. It depends on ss32, addseg and dflag.  */
gen_push_v(DisasContext * s,TCGv val)1957  static void gen_push_v(DisasContext *s, TCGv val)
1958  {
1959      MemOp d_ot = mo_pushpop(s, s->dflag);
1960      MemOp a_ot = mo_stacksize(s);
1961      int size = 1 << d_ot;
1962      TCGv new_esp = tcg_temp_new();
1963  
1964      tcg_gen_subi_tl(new_esp, cpu_regs[R_ESP], size);
1965  
1966      /* Now reduce the value to the address size and apply SS base.  */
1967      gen_lea_ss_ofs(s, s->A0, new_esp, 0);
1968      gen_op_st_v(s, d_ot, val, s->A0);
1969      gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp);
1970  }
1971  
1972  /* two step pop is necessary for precise exceptions */
gen_pop_T0(DisasContext * s)1973  static MemOp gen_pop_T0(DisasContext *s)
1974  {
1975      MemOp d_ot = mo_pushpop(s, s->dflag);
1976  
1977      gen_lea_ss_ofs(s, s->T0, cpu_regs[R_ESP], 0);
1978      gen_op_ld_v(s, d_ot, s->T0, s->T0);
1979  
1980      return d_ot;
1981  }
1982  
gen_pop_update(DisasContext * s,MemOp ot)1983  static inline void gen_pop_update(DisasContext *s, MemOp ot)
1984  {
1985      gen_stack_update(s, 1 << ot);
1986  }
1987  
gen_pusha(DisasContext * s)1988  static void gen_pusha(DisasContext *s)
1989  {
1990      MemOp d_ot = s->dflag;
1991      int size = 1 << d_ot;
1992      int i;
1993  
1994      for (i = 0; i < 8; i++) {
1995          gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], (i - 8) * size);
1996          gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0);
1997      }
1998  
1999      gen_stack_update(s, -8 * size);
2000  }
2001  
gen_popa(DisasContext * s)2002  static void gen_popa(DisasContext *s)
2003  {
2004      MemOp d_ot = s->dflag;
2005      int size = 1 << d_ot;
2006      int i;
2007  
2008      for (i = 0; i < 8; i++) {
2009          /* ESP is not reloaded */
2010          if (7 - i == R_ESP) {
2011              continue;
2012          }
2013          gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], i * size);
2014          gen_op_ld_v(s, d_ot, s->T0, s->A0);
2015          gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0);
2016      }
2017  
2018      gen_stack_update(s, 8 * size);
2019  }
2020  
gen_enter(DisasContext * s,int esp_addend,int level)2021  static void gen_enter(DisasContext *s, int esp_addend, int level)
2022  {
2023      MemOp d_ot = mo_pushpop(s, s->dflag);
2024      MemOp a_ot = mo_stacksize(s);
2025      int size = 1 << d_ot;
2026  
2027      /* Push BP; compute FrameTemp into T1.  */
2028      tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size);
2029      gen_lea_ss_ofs(s, s->A0, s->T1, 0);
2030      gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0);
2031  
2032      level &= 31;
2033      if (level != 0) {
2034          int i;
2035  
2036          /* Copy level-1 pointers from the previous frame.  */
2037          for (i = 1; i < level; ++i) {
2038              gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], -size * i);
2039              gen_op_ld_v(s, d_ot, s->tmp0, s->A0);
2040  
2041              gen_lea_ss_ofs(s, s->A0, s->T1, -size * i);
2042              gen_op_st_v(s, d_ot, s->tmp0, s->A0);
2043          }
2044  
2045          /* Push the current FrameTemp as the last level.  */
2046          gen_lea_ss_ofs(s, s->A0, s->T1, -size * level);
2047          gen_op_st_v(s, d_ot, s->T1, s->A0);
2048      }
2049  
2050      /* Copy the FrameTemp value to EBP.  */
2051      gen_op_mov_reg_v(s, d_ot, R_EBP, s->T1);
2052  
2053      /* Compute the final value of ESP.  */
2054      tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level);
2055      gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2056  }
2057  
gen_leave(DisasContext * s)2058  static void gen_leave(DisasContext *s)
2059  {
2060      MemOp d_ot = mo_pushpop(s, s->dflag);
2061      MemOp a_ot = mo_stacksize(s);
2062  
2063      gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], 0);
2064      gen_op_ld_v(s, d_ot, s->T0, s->A0);
2065  
2066      tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot);
2067  
2068      gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0);
2069      gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2070  }
2071  
2072  /* Similarly, except that the assumption here is that we don't decode
2073     the instruction at all -- either a missing opcode, an unimplemented
2074     feature, or just a bogus instruction stream.  */
gen_unknown_opcode(CPUX86State * env,DisasContext * s)2075  static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2076  {
2077      gen_illegal_opcode(s);
2078  
2079      if (qemu_loglevel_mask(LOG_UNIMP)) {
2080          FILE *logfile = qemu_log_trylock();
2081          if (logfile) {
2082              target_ulong pc = s->base.pc_next, end = s->pc;
2083  
2084              fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc);
2085              for (; pc < end; ++pc) {
2086                  fprintf(logfile, " %02x", translator_ldub(env, &s->base, pc));
2087              }
2088              fprintf(logfile, "\n");
2089              qemu_log_unlock(logfile);
2090          }
2091      }
2092  }
2093  
2094  /* an interrupt is different from an exception because of the
2095     privilege checks */
gen_interrupt(DisasContext * s,uint8_t intno)2096  static void gen_interrupt(DisasContext *s, uint8_t intno)
2097  {
2098      gen_update_cc_op(s);
2099      gen_update_eip_cur(s);
2100      gen_helper_raise_interrupt(tcg_env, tcg_constant_i32(intno),
2101                                 cur_insn_len_i32(s));
2102      s->base.is_jmp = DISAS_NORETURN;
2103  }
2104  
gen_set_hflag(DisasContext * s,uint32_t mask)2105  static void gen_set_hflag(DisasContext *s, uint32_t mask)
2106  {
2107      if ((s->flags & mask) == 0) {
2108          TCGv_i32 t = tcg_temp_new_i32();
2109          tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2110          tcg_gen_ori_i32(t, t, mask);
2111          tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2112          s->flags |= mask;
2113      }
2114  }
2115  
gen_reset_hflag(DisasContext * s,uint32_t mask)2116  static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2117  {
2118      if (s->flags & mask) {
2119          TCGv_i32 t = tcg_temp_new_i32();
2120          tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2121          tcg_gen_andi_i32(t, t, ~mask);
2122          tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2123          s->flags &= ~mask;
2124      }
2125  }
2126  
gen_set_eflags(DisasContext * s,target_ulong mask)2127  static void gen_set_eflags(DisasContext *s, target_ulong mask)
2128  {
2129      TCGv t = tcg_temp_new();
2130  
2131      tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2132      tcg_gen_ori_tl(t, t, mask);
2133      tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2134  }
2135  
gen_reset_eflags(DisasContext * s,target_ulong mask)2136  static void gen_reset_eflags(DisasContext *s, target_ulong mask)
2137  {
2138      TCGv t = tcg_temp_new();
2139  
2140      tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2141      tcg_gen_andi_tl(t, t, ~mask);
2142      tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2143  }
2144  
2145  /* Clear BND registers during legacy branches.  */
gen_bnd_jmp(DisasContext * s)2146  static void gen_bnd_jmp(DisasContext *s)
2147  {
2148      /* Clear the registers only if BND prefix is missing, MPX is enabled,
2149         and if the BNDREGs are known to be in use (non-zero) already.
2150         The helper itself will check BNDPRESERVE at runtime.  */
2151      if ((s->prefix & PREFIX_REPNZ) == 0
2152          && (s->flags & HF_MPX_EN_MASK) != 0
2153          && (s->flags & HF_MPX_IU_MASK) != 0) {
2154          gen_helper_bnd_jmp(tcg_env);
2155      }
2156  }
2157  
2158  /*
2159   * Generate an end of block, including common tasks such as generating
2160   * single step traps, resetting the RF flag, and handling the interrupt
2161   * shadow.
2162   */
2163  static void
gen_eob(DisasContext * s,int mode)2164  gen_eob(DisasContext *s, int mode)
2165  {
2166      bool inhibit_reset;
2167  
2168      gen_update_cc_op(s);
2169  
2170      /* If several instructions disable interrupts, only the first does it.  */
2171      inhibit_reset = false;
2172      if (s->flags & HF_INHIBIT_IRQ_MASK) {
2173          gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2174          inhibit_reset = true;
2175      } else if (mode == DISAS_EOB_INHIBIT_IRQ) {
2176          gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2177      }
2178  
2179      if (s->base.tb->flags & HF_RF_MASK) {
2180          gen_reset_eflags(s, RF_MASK);
2181      }
2182      if (mode == DISAS_EOB_RECHECK_TF) {
2183          gen_helper_rechecking_single_step(tcg_env);
2184          tcg_gen_exit_tb(NULL, 0);
2185      } else if ((s->flags & HF_TF_MASK) && mode != DISAS_EOB_INHIBIT_IRQ) {
2186          gen_helper_single_step(tcg_env);
2187      } else if (mode == DISAS_JUMP &&
2188                 /* give irqs a chance to happen */
2189                 !inhibit_reset) {
2190          tcg_gen_lookup_and_goto_ptr();
2191      } else {
2192          tcg_gen_exit_tb(NULL, 0);
2193      }
2194  
2195      s->base.is_jmp = DISAS_NORETURN;
2196  }
2197  
2198  /* Jump to eip+diff, truncating the result to OT. */
gen_jmp_rel(DisasContext * s,MemOp ot,int diff,int tb_num)2199  static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
2200  {
2201      bool use_goto_tb = s->jmp_opt;
2202      target_ulong mask = -1;
2203      target_ulong new_pc = s->pc + diff;
2204      target_ulong new_eip = new_pc - s->cs_base;
2205  
2206      assert(!s->cc_op_dirty);
2207  
2208      /* In 64-bit mode, operand size is fixed at 64 bits. */
2209      if (!CODE64(s)) {
2210          if (ot == MO_16) {
2211              mask = 0xffff;
2212              if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) {
2213                  use_goto_tb = false;
2214              }
2215          } else {
2216              mask = 0xffffffff;
2217          }
2218      }
2219      new_eip &= mask;
2220  
2221      if (tb_cflags(s->base.tb) & CF_PCREL) {
2222          tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save);
2223          /*
2224           * If we can prove the branch does not leave the page and we have
2225           * no extra masking to apply (data16 branch in code32, see above),
2226           * then we have also proven that the addition does not wrap.
2227           */
2228          if (!use_goto_tb || !is_same_page(&s->base, new_pc)) {
2229              tcg_gen_andi_tl(cpu_eip, cpu_eip, mask);
2230              use_goto_tb = false;
2231          }
2232      } else if (!CODE64(s)) {
2233          new_pc = (uint32_t)(new_eip + s->cs_base);
2234      }
2235  
2236      if (use_goto_tb && translator_use_goto_tb(&s->base, new_pc)) {
2237          /* jump to same page: we can use a direct jump */
2238          tcg_gen_goto_tb(tb_num);
2239          if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
2240              tcg_gen_movi_tl(cpu_eip, new_eip);
2241          }
2242          tcg_gen_exit_tb(s->base.tb, tb_num);
2243          s->base.is_jmp = DISAS_NORETURN;
2244      } else {
2245          if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
2246              tcg_gen_movi_tl(cpu_eip, new_eip);
2247          }
2248          if (s->jmp_opt) {
2249              gen_eob(s, DISAS_JUMP);   /* jump to another page */
2250          } else {
2251              gen_eob(s, DISAS_EOB_ONLY);  /* exit to main loop */
2252          }
2253      }
2254  }
2255  
2256  /* Jump to eip+diff, truncating to the current code size. */
gen_jmp_rel_csize(DisasContext * s,int diff,int tb_num)2257  static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num)
2258  {
2259      /* CODE64 ignores the OT argument, so we need not consider it. */
2260      gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num);
2261  }
2262  
gen_ldq_env_A0(DisasContext * s,int offset)2263  static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2264  {
2265      tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2266      tcg_gen_st_i64(s->tmp1_i64, tcg_env, offset);
2267  }
2268  
gen_stq_env_A0(DisasContext * s,int offset)2269  static inline void gen_stq_env_A0(DisasContext *s, int offset)
2270  {
2271      tcg_gen_ld_i64(s->tmp1_i64, tcg_env, offset);
2272      tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2273  }
2274  
gen_ldo_env_A0(DisasContext * s,int offset,bool align)2275  static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align)
2276  {
2277      MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX
2278                    ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR);
2279      MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0);
2280      int mem_index = s->mem_index;
2281      TCGv_i128 t = tcg_temp_new_i128();
2282  
2283      tcg_gen_qemu_ld_i128(t, s->A0, mem_index, mop);
2284      tcg_gen_st_i128(t, tcg_env, offset);
2285  }
2286  
gen_sto_env_A0(DisasContext * s,int offset,bool align)2287  static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align)
2288  {
2289      MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX
2290                    ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR);
2291      MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0);
2292      int mem_index = s->mem_index;
2293      TCGv_i128 t = tcg_temp_new_i128();
2294  
2295      tcg_gen_ld_i128(t, tcg_env, offset);
2296      tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop);
2297  }
2298  
gen_ldy_env_A0(DisasContext * s,int offset,bool align)2299  static void gen_ldy_env_A0(DisasContext *s, int offset, bool align)
2300  {
2301      MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR;
2302      int mem_index = s->mem_index;
2303      TCGv_i128 t0 = tcg_temp_new_i128();
2304      TCGv_i128 t1 = tcg_temp_new_i128();
2305  
2306      tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0));
2307      tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2308      tcg_gen_qemu_ld_i128(t1, s->tmp0, mem_index, mop);
2309  
2310      tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0)));
2311      tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1)));
2312  }
2313  
gen_sty_env_A0(DisasContext * s,int offset,bool align)2314  static void gen_sty_env_A0(DisasContext *s, int offset, bool align)
2315  {
2316      MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR;
2317      int mem_index = s->mem_index;
2318      TCGv_i128 t = tcg_temp_new_i128();
2319  
2320      tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0)));
2321      tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0));
2322      tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2323      tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1)));
2324      tcg_gen_qemu_st_i128(t, s->tmp0, mem_index, mop);
2325  }
2326  
2327  #include "emit.c.inc"
2328  
gen_x87(DisasContext * s,X86DecodedInsn * decode)2329  static void gen_x87(DisasContext *s, X86DecodedInsn *decode)
2330  {
2331      bool update_fip = true;
2332      int b = decode->b;
2333      int modrm = s->modrm;
2334      int mod, rm, op;
2335  
2336      if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
2337          /* if CR0.EM or CR0.TS are set, generate an FPU exception */
2338          /* XXX: what to do if illegal op ? */
2339          gen_exception(s, EXCP07_PREX);
2340          return;
2341      }
2342      mod = (modrm >> 6) & 3;
2343      rm = modrm & 7;
2344      op = ((b & 7) << 3) | ((modrm >> 3) & 7);
2345      if (mod != 3) {
2346          /* memory op */
2347          TCGv ea = gen_lea_modrm_1(s, decode->mem, false);
2348          TCGv last_addr = tcg_temp_new();
2349          bool update_fdp = true;
2350  
2351          tcg_gen_mov_tl(last_addr, ea);
2352          gen_lea_v_seg(s, ea, decode->mem.def_seg, s->override);
2353  
2354          switch (op) {
2355          case 0x00 ... 0x07: /* fxxxs */
2356          case 0x10 ... 0x17: /* fixxxl */
2357          case 0x20 ... 0x27: /* fxxxl */
2358          case 0x30 ... 0x37: /* fixxx */
2359              {
2360                  int op1;
2361                  op1 = op & 7;
2362  
2363                  switch (op >> 4) {
2364                  case 0:
2365                      tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
2366                                          s->mem_index, MO_LEUL);
2367                      gen_helper_flds_FT0(tcg_env, s->tmp2_i32);
2368                      break;
2369                  case 1:
2370                      tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
2371                                          s->mem_index, MO_LEUL);
2372                      gen_helper_fildl_FT0(tcg_env, s->tmp2_i32);
2373                      break;
2374                  case 2:
2375                      tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
2376                                          s->mem_index, MO_LEUQ);
2377                      gen_helper_fldl_FT0(tcg_env, s->tmp1_i64);
2378                      break;
2379                  case 3:
2380                  default:
2381                      tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
2382                                          s->mem_index, MO_LESW);
2383                      gen_helper_fildl_FT0(tcg_env, s->tmp2_i32);
2384                      break;
2385                  }
2386  
2387                  gen_helper_fp_arith_ST0_FT0(op1);
2388                  if (op1 == 3) {
2389                      /* fcomp needs pop */
2390                      gen_helper_fpop(tcg_env);
2391                  }
2392              }
2393              break;
2394          case 0x08: /* flds */
2395          case 0x0a: /* fsts */
2396          case 0x0b: /* fstps */
2397          case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
2398          case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
2399          case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
2400              switch (op & 7) {
2401              case 0:
2402                  switch (op >> 4) {
2403                  case 0:
2404                      tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
2405                                          s->mem_index, MO_LEUL);
2406                      gen_helper_flds_ST0(tcg_env, s->tmp2_i32);
2407                      break;
2408                  case 1:
2409                      tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
2410                                          s->mem_index, MO_LEUL);
2411                      gen_helper_fildl_ST0(tcg_env, s->tmp2_i32);
2412                      break;
2413                  case 2:
2414                      tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
2415                                          s->mem_index, MO_LEUQ);
2416                      gen_helper_fldl_ST0(tcg_env, s->tmp1_i64);
2417                      break;
2418                  case 3:
2419                  default:
2420                      tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
2421                                          s->mem_index, MO_LESW);
2422                      gen_helper_fildl_ST0(tcg_env, s->tmp2_i32);
2423                      break;
2424                  }
2425                  break;
2426              case 1:
2427                  /* XXX: the corresponding CPUID bit must be tested ! */
2428                  switch (op >> 4) {
2429                  case 1:
2430                      gen_helper_fisttl_ST0(s->tmp2_i32, tcg_env);
2431                      tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
2432                                          s->mem_index, MO_LEUL);
2433                      break;
2434                  case 2:
2435                      gen_helper_fisttll_ST0(s->tmp1_i64, tcg_env);
2436                      tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
2437                                          s->mem_index, MO_LEUQ);
2438                      break;
2439                  case 3:
2440                  default:
2441                      gen_helper_fistt_ST0(s->tmp2_i32, tcg_env);
2442                      tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
2443                                          s->mem_index, MO_LEUW);
2444                      break;
2445                  }
2446                  gen_helper_fpop(tcg_env);
2447                  break;
2448              default:
2449                  switch (op >> 4) {
2450                  case 0:
2451                      gen_helper_fsts_ST0(s->tmp2_i32, tcg_env);
2452                      tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
2453                                          s->mem_index, MO_LEUL);
2454                      break;
2455                  case 1:
2456                      gen_helper_fistl_ST0(s->tmp2_i32, tcg_env);
2457                      tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
2458                                          s->mem_index, MO_LEUL);
2459                      break;
2460                  case 2:
2461                      gen_helper_fstl_ST0(s->tmp1_i64, tcg_env);
2462                      tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
2463                                          s->mem_index, MO_LEUQ);
2464                      break;
2465                  case 3:
2466                  default:
2467                      gen_helper_fist_ST0(s->tmp2_i32, tcg_env);
2468                      tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
2469                                          s->mem_index, MO_LEUW);
2470                      break;
2471                  }
2472                  if ((op & 7) == 3) {
2473                      gen_helper_fpop(tcg_env);
2474                  }
2475                  break;
2476              }
2477              break;
2478          case 0x0c: /* fldenv mem */
2479              gen_helper_fldenv(tcg_env, s->A0,
2480                                tcg_constant_i32(s->dflag - 1));
2481              update_fip = update_fdp = false;
2482              break;
2483          case 0x0d: /* fldcw mem */
2484              tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
2485                                  s->mem_index, MO_LEUW);
2486              gen_helper_fldcw(tcg_env, s->tmp2_i32);
2487              update_fip = update_fdp = false;
2488              break;
2489          case 0x0e: /* fnstenv mem */
2490              gen_helper_fstenv(tcg_env, s->A0,
2491                                tcg_constant_i32(s->dflag - 1));
2492              update_fip = update_fdp = false;
2493              break;
2494          case 0x0f: /* fnstcw mem */
2495              gen_helper_fnstcw(s->tmp2_i32, tcg_env);
2496              tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
2497                                  s->mem_index, MO_LEUW);
2498              update_fip = update_fdp = false;
2499              break;
2500          case 0x1d: /* fldt mem */
2501              gen_helper_fldt_ST0(tcg_env, s->A0);
2502              break;
2503          case 0x1f: /* fstpt mem */
2504              gen_helper_fstt_ST0(tcg_env, s->A0);
2505              gen_helper_fpop(tcg_env);
2506              break;
2507          case 0x2c: /* frstor mem */
2508              gen_helper_frstor(tcg_env, s->A0,
2509                                tcg_constant_i32(s->dflag - 1));
2510              update_fip = update_fdp = false;
2511              break;
2512          case 0x2e: /* fnsave mem */
2513              gen_helper_fsave(tcg_env, s->A0,
2514                               tcg_constant_i32(s->dflag - 1));
2515              update_fip = update_fdp = false;
2516              break;
2517          case 0x2f: /* fnstsw mem */
2518              gen_helper_fnstsw(s->tmp2_i32, tcg_env);
2519              tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
2520                                  s->mem_index, MO_LEUW);
2521              update_fip = update_fdp = false;
2522              break;
2523          case 0x3c: /* fbld */
2524              gen_helper_fbld_ST0(tcg_env, s->A0);
2525              break;
2526          case 0x3e: /* fbstp */
2527              gen_helper_fbst_ST0(tcg_env, s->A0);
2528              gen_helper_fpop(tcg_env);
2529              break;
2530          case 0x3d: /* fildll */
2531              tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
2532                                  s->mem_index, MO_LEUQ);
2533              gen_helper_fildll_ST0(tcg_env, s->tmp1_i64);
2534              break;
2535          case 0x3f: /* fistpll */
2536              gen_helper_fistll_ST0(s->tmp1_i64, tcg_env);
2537              tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
2538                                  s->mem_index, MO_LEUQ);
2539              gen_helper_fpop(tcg_env);
2540              break;
2541          default:
2542              goto illegal_op;
2543          }
2544  
2545          if (update_fdp) {
2546              int last_seg = s->override >= 0 ? s->override : decode->mem.def_seg;
2547  
2548              tcg_gen_ld_i32(s->tmp2_i32, tcg_env,
2549                             offsetof(CPUX86State,
2550                                      segs[last_seg].selector));
2551              tcg_gen_st16_i32(s->tmp2_i32, tcg_env,
2552                               offsetof(CPUX86State, fpds));
2553              tcg_gen_st_tl(last_addr, tcg_env,
2554                            offsetof(CPUX86State, fpdp));
2555          }
2556      } else {
2557          /* register float ops */
2558          int opreg = rm;
2559  
2560          switch (op) {
2561          case 0x08: /* fld sti */
2562              gen_helper_fpush(tcg_env);
2563              gen_helper_fmov_ST0_STN(tcg_env,
2564                                      tcg_constant_i32((opreg + 1) & 7));
2565              break;
2566          case 0x09: /* fxchg sti */
2567          case 0x29: /* fxchg4 sti, undocumented op */
2568          case 0x39: /* fxchg7 sti, undocumented op */
2569              gen_helper_fxchg_ST0_STN(tcg_env, tcg_constant_i32(opreg));
2570              break;
2571          case 0x0a: /* grp d9/2 */
2572              switch (rm) {
2573              case 0: /* fnop */
2574                  /*
2575                   * check exceptions (FreeBSD FPU probe)
2576                   * needs to be treated as I/O because of ferr_irq
2577                   */
2578                  translator_io_start(&s->base);
2579                  gen_helper_fwait(tcg_env);
2580                  update_fip = false;
2581                  break;
2582              default:
2583                  goto illegal_op;
2584              }
2585              break;
2586          case 0x0c: /* grp d9/4 */
2587              switch (rm) {
2588              case 0: /* fchs */
2589                  gen_helper_fchs_ST0(tcg_env);
2590                  break;
2591              case 1: /* fabs */
2592                  gen_helper_fabs_ST0(tcg_env);
2593                  break;
2594              case 4: /* ftst */
2595                  gen_helper_fldz_FT0(tcg_env);
2596                  gen_helper_fcom_ST0_FT0(tcg_env);
2597                  break;
2598              case 5: /* fxam */
2599                  gen_helper_fxam_ST0(tcg_env);
2600                  break;
2601              default:
2602                  goto illegal_op;
2603              }
2604              break;
2605          case 0x0d: /* grp d9/5 */
2606              {
2607                  switch (rm) {
2608                  case 0:
2609                      gen_helper_fpush(tcg_env);
2610                      gen_helper_fld1_ST0(tcg_env);
2611                      break;
2612                  case 1:
2613                      gen_helper_fpush(tcg_env);
2614                      gen_helper_fldl2t_ST0(tcg_env);
2615                      break;
2616                  case 2:
2617                      gen_helper_fpush(tcg_env);
2618                      gen_helper_fldl2e_ST0(tcg_env);
2619                      break;
2620                  case 3:
2621                      gen_helper_fpush(tcg_env);
2622                      gen_helper_fldpi_ST0(tcg_env);
2623                      break;
2624                  case 4:
2625                      gen_helper_fpush(tcg_env);
2626                      gen_helper_fldlg2_ST0(tcg_env);
2627                      break;
2628                  case 5:
2629                      gen_helper_fpush(tcg_env);
2630                      gen_helper_fldln2_ST0(tcg_env);
2631                      break;
2632                  case 6:
2633                      gen_helper_fpush(tcg_env);
2634                      gen_helper_fldz_ST0(tcg_env);
2635                      break;
2636                  default:
2637                      goto illegal_op;
2638                  }
2639              }
2640              break;
2641          case 0x0e: /* grp d9/6 */
2642              switch (rm) {
2643              case 0: /* f2xm1 */
2644                  gen_helper_f2xm1(tcg_env);
2645                  break;
2646              case 1: /* fyl2x */
2647                  gen_helper_fyl2x(tcg_env);
2648                  break;
2649              case 2: /* fptan */
2650                  gen_helper_fptan(tcg_env);
2651                  break;
2652              case 3: /* fpatan */
2653                  gen_helper_fpatan(tcg_env);
2654                  break;
2655              case 4: /* fxtract */
2656                  gen_helper_fxtract(tcg_env);
2657                  break;
2658              case 5: /* fprem1 */
2659                  gen_helper_fprem1(tcg_env);
2660                  break;
2661              case 6: /* fdecstp */
2662                  gen_helper_fdecstp(tcg_env);
2663                  break;
2664              default:
2665              case 7: /* fincstp */
2666                  gen_helper_fincstp(tcg_env);
2667                  break;
2668              }
2669              break;
2670          case 0x0f: /* grp d9/7 */
2671              switch (rm) {
2672              case 0: /* fprem */
2673                  gen_helper_fprem(tcg_env);
2674                  break;
2675              case 1: /* fyl2xp1 */
2676                  gen_helper_fyl2xp1(tcg_env);
2677                  break;
2678              case 2: /* fsqrt */
2679                  gen_helper_fsqrt(tcg_env);
2680                  break;
2681              case 3: /* fsincos */
2682                  gen_helper_fsincos(tcg_env);
2683                  break;
2684              case 5: /* fscale */
2685                  gen_helper_fscale(tcg_env);
2686                  break;
2687              case 4: /* frndint */
2688                  gen_helper_frndint(tcg_env);
2689                  break;
2690              case 6: /* fsin */
2691                  gen_helper_fsin(tcg_env);
2692                  break;
2693              default:
2694              case 7: /* fcos */
2695                  gen_helper_fcos(tcg_env);
2696                  break;
2697              }
2698              break;
2699          case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
2700          case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
2701          case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
2702              {
2703                  int op1;
2704  
2705                  op1 = op & 7;
2706                  if (op >= 0x20) {
2707                      gen_helper_fp_arith_STN_ST0(op1, opreg);
2708                      if (op >= 0x30) {
2709                          gen_helper_fpop(tcg_env);
2710                      }
2711                  } else {
2712                      gen_helper_fmov_FT0_STN(tcg_env,
2713                                              tcg_constant_i32(opreg));
2714                      gen_helper_fp_arith_ST0_FT0(op1);
2715                  }
2716              }
2717              break;
2718          case 0x02: /* fcom */
2719          case 0x22: /* fcom2, undocumented op */
2720              gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
2721              gen_helper_fcom_ST0_FT0(tcg_env);
2722              break;
2723          case 0x03: /* fcomp */
2724          case 0x23: /* fcomp3, undocumented op */
2725          case 0x32: /* fcomp5, undocumented op */
2726              gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
2727              gen_helper_fcom_ST0_FT0(tcg_env);
2728              gen_helper_fpop(tcg_env);
2729              break;
2730          case 0x15: /* da/5 */
2731              switch (rm) {
2732              case 1: /* fucompp */
2733                  gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1));
2734                  gen_helper_fucom_ST0_FT0(tcg_env);
2735                  gen_helper_fpop(tcg_env);
2736                  gen_helper_fpop(tcg_env);
2737                  break;
2738              default:
2739                  goto illegal_op;
2740              }
2741              break;
2742          case 0x1c:
2743              switch (rm) {
2744              case 0: /* feni (287 only, just do nop here) */
2745                  break;
2746              case 1: /* fdisi (287 only, just do nop here) */
2747                  break;
2748              case 2: /* fclex */
2749                  gen_helper_fclex(tcg_env);
2750                  update_fip = false;
2751                  break;
2752              case 3: /* fninit */
2753                  gen_helper_fninit(tcg_env);
2754                  update_fip = false;
2755                  break;
2756              case 4: /* fsetpm (287 only, just do nop here) */
2757                  break;
2758              default:
2759                  goto illegal_op;
2760              }
2761              break;
2762          case 0x1d: /* fucomi */
2763              if (!(s->cpuid_features & CPUID_CMOV)) {
2764                  goto illegal_op;
2765              }
2766              gen_update_cc_op(s);
2767              gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
2768              gen_helper_fucomi_ST0_FT0(tcg_env);
2769              assume_cc_op(s, CC_OP_EFLAGS);
2770              break;
2771          case 0x1e: /* fcomi */
2772              if (!(s->cpuid_features & CPUID_CMOV)) {
2773                  goto illegal_op;
2774              }
2775              gen_update_cc_op(s);
2776              gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
2777              gen_helper_fcomi_ST0_FT0(tcg_env);
2778              assume_cc_op(s, CC_OP_EFLAGS);
2779              break;
2780          case 0x28: /* ffree sti */
2781              gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg));
2782              break;
2783          case 0x2a: /* fst sti */
2784              gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg));
2785              break;
2786          case 0x2b: /* fstp sti */
2787          case 0x0b: /* fstp1 sti, undocumented op */
2788          case 0x3a: /* fstp8 sti, undocumented op */
2789          case 0x3b: /* fstp9 sti, undocumented op */
2790              gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg));
2791              gen_helper_fpop(tcg_env);
2792              break;
2793          case 0x2c: /* fucom st(i) */
2794              gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
2795              gen_helper_fucom_ST0_FT0(tcg_env);
2796              break;
2797          case 0x2d: /* fucomp st(i) */
2798              gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
2799              gen_helper_fucom_ST0_FT0(tcg_env);
2800              gen_helper_fpop(tcg_env);
2801              break;
2802          case 0x33: /* de/3 */
2803              switch (rm) {
2804              case 1: /* fcompp */
2805                  gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1));
2806                  gen_helper_fcom_ST0_FT0(tcg_env);
2807                  gen_helper_fpop(tcg_env);
2808                  gen_helper_fpop(tcg_env);
2809                  break;
2810              default:
2811                  goto illegal_op;
2812              }
2813              break;
2814          case 0x38: /* ffreep sti, undocumented op */
2815              gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg));
2816              gen_helper_fpop(tcg_env);
2817              break;
2818          case 0x3c: /* df/4 */
2819              switch (rm) {
2820              case 0:
2821                  gen_helper_fnstsw(s->tmp2_i32, tcg_env);
2822                  tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
2823                  gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
2824                  break;
2825              default:
2826                  goto illegal_op;
2827              }
2828              break;
2829          case 0x3d: /* fucomip */
2830              if (!(s->cpuid_features & CPUID_CMOV)) {
2831                  goto illegal_op;
2832              }
2833              gen_update_cc_op(s);
2834              gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
2835              gen_helper_fucomi_ST0_FT0(tcg_env);
2836              gen_helper_fpop(tcg_env);
2837              assume_cc_op(s, CC_OP_EFLAGS);
2838              break;
2839          case 0x3e: /* fcomip */
2840              if (!(s->cpuid_features & CPUID_CMOV)) {
2841                  goto illegal_op;
2842              }
2843              gen_update_cc_op(s);
2844              gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
2845              gen_helper_fcomi_ST0_FT0(tcg_env);
2846              gen_helper_fpop(tcg_env);
2847              assume_cc_op(s, CC_OP_EFLAGS);
2848              break;
2849          case 0x10 ... 0x13: /* fcmovxx */
2850          case 0x18 ... 0x1b:
2851              {
2852                  int op1;
2853                  TCGLabel *l1;
2854                  static const uint8_t fcmov_cc[8] = {
2855                      (JCC_B << 1),
2856                      (JCC_Z << 1),
2857                      (JCC_BE << 1),
2858                      (JCC_P << 1),
2859                  };
2860  
2861                  if (!(s->cpuid_features & CPUID_CMOV)) {
2862                      goto illegal_op;
2863                  }
2864                  op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
2865                  l1 = gen_new_label();
2866                  gen_jcc1_noeob(s, op1, l1);
2867                  gen_helper_fmov_ST0_STN(tcg_env,
2868                                          tcg_constant_i32(opreg));
2869                  gen_set_label(l1);
2870              }
2871              break;
2872          default:
2873              goto illegal_op;
2874          }
2875      }
2876  
2877      if (update_fip) {
2878          tcg_gen_ld_i32(s->tmp2_i32, tcg_env,
2879                         offsetof(CPUX86State, segs[R_CS].selector));
2880          tcg_gen_st16_i32(s->tmp2_i32, tcg_env,
2881                           offsetof(CPUX86State, fpcs));
2882          tcg_gen_st_tl(eip_cur_tl(s),
2883                        tcg_env, offsetof(CPUX86State, fpip));
2884      }
2885      return;
2886  
2887   illegal_op:
2888      gen_illegal_opcode(s);
2889  }
2890  
gen_multi0F(DisasContext * s,X86DecodedInsn * decode)2891  static void gen_multi0F(DisasContext *s, X86DecodedInsn *decode)
2892  {
2893      int prefixes = s->prefix;
2894      MemOp dflag = s->dflag;
2895      int b = decode->b + 0x100;
2896      int modrm = s->modrm;
2897      MemOp ot;
2898      int reg, rm, mod, op;
2899  
2900      /* now check op code */
2901      switch (b) {
2902      case 0x1c7: /* RDSEED, RDPID with f3 prefix */
2903          mod = (modrm >> 6) & 3;
2904          switch ((modrm >> 3) & 7) {
2905          case 7:
2906              if (mod != 3 ||
2907                  (s->prefix & PREFIX_REPNZ)) {
2908                  goto illegal_op;
2909              }
2910              if (s->prefix & PREFIX_REPZ) {
2911                  if (!(s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_RDPID)) {
2912                      goto illegal_op;
2913                  }
2914                  gen_helper_rdpid(s->T0, tcg_env);
2915                  rm = (modrm & 7) | REX_B(s);
2916                  gen_op_mov_reg_v(s, dflag, rm, s->T0);
2917                  break;
2918              } else {
2919                  if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) {
2920                      goto illegal_op;
2921                  }
2922                  goto do_rdrand;
2923              }
2924  
2925          case 6: /* RDRAND */
2926              if (mod != 3 ||
2927                  (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) ||
2928                  !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
2929                  goto illegal_op;
2930              }
2931          do_rdrand:
2932              translator_io_start(&s->base);
2933              gen_helper_rdrand(s->T0, tcg_env);
2934              rm = (modrm & 7) | REX_B(s);
2935              gen_op_mov_reg_v(s, dflag, rm, s->T0);
2936              assume_cc_op(s, CC_OP_EFLAGS);
2937              break;
2938  
2939          default:
2940              goto illegal_op;
2941          }
2942          break;
2943  
2944      case 0x100:
2945          mod = (modrm >> 6) & 3;
2946          op = (modrm >> 3) & 7;
2947          switch(op) {
2948          case 0: /* sldt */
2949              if (!PE(s) || VM86(s))
2950                  goto illegal_op;
2951              if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
2952                  break;
2953              }
2954              gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ);
2955              tcg_gen_ld32u_tl(s->T0, tcg_env,
2956                               offsetof(CPUX86State, ldt.selector));
2957              ot = mod == 3 ? dflag : MO_16;
2958              gen_st_modrm(s, decode, ot);
2959              break;
2960          case 2: /* lldt */
2961              if (!PE(s) || VM86(s))
2962                  goto illegal_op;
2963              if (check_cpl0(s)) {
2964                  gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE);
2965                  gen_ld_modrm(s, decode, MO_16);
2966                  tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
2967                  gen_helper_lldt(tcg_env, s->tmp2_i32);
2968              }
2969              break;
2970          case 1: /* str */
2971              if (!PE(s) || VM86(s))
2972                  goto illegal_op;
2973              if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
2974                  break;
2975              }
2976              gen_svm_check_intercept(s, SVM_EXIT_TR_READ);
2977              tcg_gen_ld32u_tl(s->T0, tcg_env,
2978                               offsetof(CPUX86State, tr.selector));
2979              ot = mod == 3 ? dflag : MO_16;
2980              gen_st_modrm(s, decode, ot);
2981              break;
2982          case 3: /* ltr */
2983              if (!PE(s) || VM86(s))
2984                  goto illegal_op;
2985              if (check_cpl0(s)) {
2986                  gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE);
2987                  gen_ld_modrm(s, decode, MO_16);
2988                  tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
2989                  gen_helper_ltr(tcg_env, s->tmp2_i32);
2990              }
2991              break;
2992          case 4: /* verr */
2993          case 5: /* verw */
2994              if (!PE(s) || VM86(s))
2995                  goto illegal_op;
2996              gen_ld_modrm(s, decode, MO_16);
2997              gen_update_cc_op(s);
2998              if (op == 4) {
2999                  gen_helper_verr(tcg_env, s->T0);
3000              } else {
3001                  gen_helper_verw(tcg_env, s->T0);
3002              }
3003              assume_cc_op(s, CC_OP_EFLAGS);
3004              break;
3005          default:
3006              goto illegal_op;
3007          }
3008          break;
3009  
3010      case 0x101:
3011          switch (modrm) {
3012          CASE_MODRM_MEM_OP(0): /* sgdt */
3013              if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
3014                  break;
3015              }
3016              gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ);
3017              gen_lea_modrm(s, decode);
3018              tcg_gen_ld32u_tl(s->T0,
3019                               tcg_env, offsetof(CPUX86State, gdt.limit));
3020              gen_op_st_v(s, MO_16, s->T0, s->A0);
3021              gen_add_A0_im(s, 2);
3022              tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base));
3023              /*
3024               * NB: Despite a confusing description in Intel CPU documentation,
3025               *     all 32-bits are written regardless of operand size.
3026               */
3027              gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
3028              break;
3029  
3030          case 0xc8: /* monitor */
3031              if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
3032                  goto illegal_op;
3033              }
3034              gen_update_cc_op(s);
3035              gen_update_eip_cur(s);
3036              gen_lea_v_seg(s, cpu_regs[R_EAX], R_DS, s->override);
3037              gen_helper_monitor(tcg_env, s->A0);
3038              break;
3039  
3040          case 0xc9: /* mwait */
3041              if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
3042                  goto illegal_op;
3043              }
3044              gen_update_cc_op(s);
3045              gen_update_eip_cur(s);
3046              gen_helper_mwait(tcg_env, cur_insn_len_i32(s));
3047              s->base.is_jmp = DISAS_NORETURN;
3048              break;
3049  
3050          case 0xca: /* clac */
3051              if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
3052                  || CPL(s) != 0) {
3053                  goto illegal_op;
3054              }
3055              gen_reset_eflags(s, AC_MASK);
3056              s->base.is_jmp = DISAS_EOB_NEXT;
3057              break;
3058  
3059          case 0xcb: /* stac */
3060              if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
3061                  || CPL(s) != 0) {
3062                  goto illegal_op;
3063              }
3064              gen_set_eflags(s, AC_MASK);
3065              s->base.is_jmp = DISAS_EOB_NEXT;
3066              break;
3067  
3068          CASE_MODRM_MEM_OP(1): /* sidt */
3069              if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
3070                  break;
3071              }
3072              gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ);
3073              gen_lea_modrm(s, decode);
3074              tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.limit));
3075              gen_op_st_v(s, MO_16, s->T0, s->A0);
3076              gen_add_A0_im(s, 2);
3077              tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base));
3078              /*
3079               * NB: Despite a confusing description in Intel CPU documentation,
3080               *     all 32-bits are written regardless of operand size.
3081               */
3082              gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
3083              break;
3084  
3085          case 0xd0: /* xgetbv */
3086              if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
3087                  || (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) {
3088                  goto illegal_op;
3089              }
3090              tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
3091              gen_helper_xgetbv(s->tmp1_i64, tcg_env, s->tmp2_i32);
3092              tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
3093              break;
3094  
3095          case 0xd1: /* xsetbv */
3096              if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
3097                  || (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) {
3098                  goto illegal_op;
3099              }
3100              gen_svm_check_intercept(s, SVM_EXIT_XSETBV);
3101              if (!check_cpl0(s)) {
3102                  break;
3103              }
3104              tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
3105                                    cpu_regs[R_EDX]);
3106              tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
3107              gen_helper_xsetbv(tcg_env, s->tmp2_i32, s->tmp1_i64);
3108              /* End TB because translation flags may change.  */
3109              s->base.is_jmp = DISAS_EOB_NEXT;
3110              break;
3111  
3112          case 0xd8: /* VMRUN */
3113              if (!SVME(s) || !PE(s)) {
3114                  goto illegal_op;
3115              }
3116              if (!check_cpl0(s)) {
3117                  break;
3118              }
3119              gen_update_cc_op(s);
3120              gen_update_eip_cur(s);
3121              /*
3122               * Reloads INHIBIT_IRQ mask as well as TF and RF with guest state.
3123               * The usual gen_eob() handling is performed on vmexit after
3124               * host state is reloaded.
3125               */
3126              gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1),
3127                               cur_insn_len_i32(s));
3128              tcg_gen_exit_tb(NULL, 0);
3129              s->base.is_jmp = DISAS_NORETURN;
3130              break;
3131  
3132          case 0xd9: /* VMMCALL */
3133              if (!SVME(s)) {
3134                  goto illegal_op;
3135              }
3136              gen_update_cc_op(s);
3137              gen_update_eip_cur(s);
3138              gen_helper_vmmcall(tcg_env);
3139              break;
3140  
3141          case 0xda: /* VMLOAD */
3142              if (!SVME(s) || !PE(s)) {
3143                  goto illegal_op;
3144              }
3145              if (!check_cpl0(s)) {
3146                  break;
3147              }
3148              gen_update_cc_op(s);
3149              gen_update_eip_cur(s);
3150              gen_helper_vmload(tcg_env, tcg_constant_i32(s->aflag - 1));
3151              break;
3152  
3153          case 0xdb: /* VMSAVE */
3154              if (!SVME(s) || !PE(s)) {
3155                  goto illegal_op;
3156              }
3157              if (!check_cpl0(s)) {
3158                  break;
3159              }
3160              gen_update_cc_op(s);
3161              gen_update_eip_cur(s);
3162              gen_helper_vmsave(tcg_env, tcg_constant_i32(s->aflag - 1));
3163              break;
3164  
3165          case 0xdc: /* STGI */
3166              if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
3167                  || !PE(s)) {
3168                  goto illegal_op;
3169              }
3170              if (!check_cpl0(s)) {
3171                  break;
3172              }
3173              gen_update_cc_op(s);
3174              gen_helper_stgi(tcg_env);
3175              s->base.is_jmp = DISAS_EOB_NEXT;
3176              break;
3177  
3178          case 0xdd: /* CLGI */
3179              if (!SVME(s) || !PE(s)) {
3180                  goto illegal_op;
3181              }
3182              if (!check_cpl0(s)) {
3183                  break;
3184              }
3185              gen_update_cc_op(s);
3186              gen_update_eip_cur(s);
3187              gen_helper_clgi(tcg_env);
3188              break;
3189  
3190          case 0xde: /* SKINIT */
3191              if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
3192                  || !PE(s)) {
3193                  goto illegal_op;
3194              }
3195              gen_svm_check_intercept(s, SVM_EXIT_SKINIT);
3196              /* If not intercepted, not implemented -- raise #UD. */
3197              goto illegal_op;
3198  
3199          case 0xdf: /* INVLPGA */
3200              if (!SVME(s) || !PE(s)) {
3201                  goto illegal_op;
3202              }
3203              if (!check_cpl0(s)) {
3204                  break;
3205              }
3206              gen_svm_check_intercept(s, SVM_EXIT_INVLPGA);
3207              if (s->aflag == MO_64) {
3208                  tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
3209              } else {
3210                  tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
3211              }
3212              gen_helper_flush_page(tcg_env, s->A0);
3213              s->base.is_jmp = DISAS_EOB_NEXT;
3214              break;
3215  
3216          CASE_MODRM_MEM_OP(2): /* lgdt */
3217              if (!check_cpl0(s)) {
3218                  break;
3219              }
3220              gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE);
3221              gen_lea_modrm(s, decode);
3222              gen_op_ld_v(s, MO_16, s->T1, s->A0);
3223              gen_add_A0_im(s, 2);
3224              gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
3225              if (dflag == MO_16) {
3226                  tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
3227              }
3228              tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base));
3229              tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, gdt.limit));
3230              break;
3231  
3232          CASE_MODRM_MEM_OP(3): /* lidt */
3233              if (!check_cpl0(s)) {
3234                  break;
3235              }
3236              gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE);
3237              gen_lea_modrm(s, decode);
3238              gen_op_ld_v(s, MO_16, s->T1, s->A0);
3239              gen_add_A0_im(s, 2);
3240              gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
3241              if (dflag == MO_16) {
3242                  tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
3243              }
3244              tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base));
3245              tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, idt.limit));
3246              break;
3247  
3248          CASE_MODRM_OP(4): /* smsw */
3249              if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
3250                  break;
3251              }
3252              gen_svm_check_intercept(s, SVM_EXIT_READ_CR0);
3253              tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, cr[0]));
3254              /*
3255               * In 32-bit mode, the higher 16 bits of the destination
3256               * register are undefined.  In practice CR0[31:0] is stored
3257               * just like in 64-bit mode.
3258               */
3259              mod = (modrm >> 6) & 3;
3260              ot = (mod != 3 ? MO_16 : s->dflag);
3261              gen_st_modrm(s, decode, ot);
3262              break;
3263          case 0xee: /* rdpkru */
3264              if (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ)) {
3265                  goto illegal_op;
3266              }
3267              tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
3268              gen_helper_rdpkru(s->tmp1_i64, tcg_env, s->tmp2_i32);
3269              tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
3270              break;
3271          case 0xef: /* wrpkru */
3272              if (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ)) {
3273                  goto illegal_op;
3274              }
3275              tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
3276                                    cpu_regs[R_EDX]);
3277              tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
3278              gen_helper_wrpkru(tcg_env, s->tmp2_i32, s->tmp1_i64);
3279              break;
3280  
3281          CASE_MODRM_OP(6): /* lmsw */
3282              if (!check_cpl0(s)) {
3283                  break;
3284              }
3285              gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
3286              gen_ld_modrm(s, decode, MO_16);
3287              /*
3288               * Only the 4 lower bits of CR0 are modified.
3289               * PE cannot be set to zero if already set to one.
3290               */
3291              tcg_gen_ld_tl(s->T1, tcg_env, offsetof(CPUX86State, cr[0]));
3292              tcg_gen_andi_tl(s->T0, s->T0, 0xf);
3293              tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
3294              tcg_gen_or_tl(s->T0, s->T0, s->T1);
3295              gen_helper_write_crN(tcg_env, tcg_constant_i32(0), s->T0);
3296              s->base.is_jmp = DISAS_EOB_NEXT;
3297              break;
3298  
3299          CASE_MODRM_MEM_OP(7): /* invlpg */
3300              if (!check_cpl0(s)) {
3301                  break;
3302              }
3303              gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
3304              gen_lea_modrm(s, decode);
3305              gen_helper_flush_page(tcg_env, s->A0);
3306              s->base.is_jmp = DISAS_EOB_NEXT;
3307              break;
3308  
3309          case 0xf8: /* swapgs */
3310  #ifdef TARGET_X86_64
3311              if (CODE64(s)) {
3312                  if (check_cpl0(s)) {
3313                      tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
3314                      tcg_gen_ld_tl(cpu_seg_base[R_GS], tcg_env,
3315                                    offsetof(CPUX86State, kernelgsbase));
3316                      tcg_gen_st_tl(s->T0, tcg_env,
3317                                    offsetof(CPUX86State, kernelgsbase));
3318                  }
3319                  break;
3320              }
3321  #endif
3322              goto illegal_op;
3323  
3324          case 0xf9: /* rdtscp */
3325              if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
3326                  goto illegal_op;
3327              }
3328              gen_update_cc_op(s);
3329              gen_update_eip_cur(s);
3330              translator_io_start(&s->base);
3331              gen_helper_rdtsc(tcg_env);
3332              gen_helper_rdpid(s->T0, tcg_env);
3333              gen_op_mov_reg_v(s, dflag, R_ECX, s->T0);
3334              break;
3335  
3336          default:
3337              goto illegal_op;
3338          }
3339          break;
3340  
3341      case 0x11a:
3342          if (s->flags & HF_MPX_EN_MASK) {
3343              mod = (modrm >> 6) & 3;
3344              reg = ((modrm >> 3) & 7) | REX_R(s);
3345              if (prefixes & PREFIX_REPZ) {
3346                  /* bndcl */
3347                  if (reg >= 4
3348                      || s->aflag == MO_16) {
3349                      goto illegal_op;
3350                  }
3351                  gen_bndck(s, decode, TCG_COND_LTU, cpu_bndl[reg]);
3352              } else if (prefixes & PREFIX_REPNZ) {
3353                  /* bndcu */
3354                  if (reg >= 4
3355                      || s->aflag == MO_16) {
3356                      goto illegal_op;
3357                  }
3358                  TCGv_i64 notu = tcg_temp_new_i64();
3359                  tcg_gen_not_i64(notu, cpu_bndu[reg]);
3360                  gen_bndck(s, decode, TCG_COND_GTU, notu);
3361              } else if (prefixes & PREFIX_DATA) {
3362                  /* bndmov -- from reg/mem */
3363                  if (reg >= 4 || s->aflag == MO_16) {
3364                      goto illegal_op;
3365                  }
3366                  if (mod == 3) {
3367                      int reg2 = (modrm & 7) | REX_B(s);
3368                      if (reg2 >= 4) {
3369                          goto illegal_op;
3370                      }
3371                      if (s->flags & HF_MPX_IU_MASK) {
3372                          tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
3373                          tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
3374                      }
3375                  } else {
3376                      gen_lea_modrm(s, decode);
3377                      if (CODE64(s)) {
3378                          tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
3379                                              s->mem_index, MO_LEUQ);
3380                          tcg_gen_addi_tl(s->A0, s->A0, 8);
3381                          tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
3382                                              s->mem_index, MO_LEUQ);
3383                      } else {
3384                          tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
3385                                              s->mem_index, MO_LEUL);
3386                          tcg_gen_addi_tl(s->A0, s->A0, 4);
3387                          tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
3388                                              s->mem_index, MO_LEUL);
3389                      }
3390                      /* bnd registers are now in-use */
3391                      gen_set_hflag(s, HF_MPX_IU_MASK);
3392                  }
3393              } else if (mod != 3) {
3394                  /* bndldx */
3395                  AddressParts a = decode->mem;
3396                  if (reg >= 4
3397                      || s->aflag == MO_16
3398                      || a.base < -1) {
3399                      goto illegal_op;
3400                  }
3401                  if (a.base >= 0) {
3402                      tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
3403                  } else {
3404                      tcg_gen_movi_tl(s->A0, 0);
3405                  }
3406                  gen_lea_v_seg(s, s->A0, a.def_seg, s->override);
3407                  if (a.index >= 0) {
3408                      tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
3409                  } else {
3410                      tcg_gen_movi_tl(s->T0, 0);
3411                  }
3412                  if (CODE64(s)) {
3413                      gen_helper_bndldx64(cpu_bndl[reg], tcg_env, s->A0, s->T0);
3414                      tcg_gen_ld_i64(cpu_bndu[reg], tcg_env,
3415                                     offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
3416                  } else {
3417                      gen_helper_bndldx32(cpu_bndu[reg], tcg_env, s->A0, s->T0);
3418                      tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
3419                      tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
3420                  }
3421                  gen_set_hflag(s, HF_MPX_IU_MASK);
3422              }
3423          }
3424          break;
3425      case 0x11b:
3426          if (s->flags & HF_MPX_EN_MASK) {
3427              mod = (modrm >> 6) & 3;
3428              reg = ((modrm >> 3) & 7) | REX_R(s);
3429              if (mod != 3 && (prefixes & PREFIX_REPZ)) {
3430                  /* bndmk */
3431                  if (reg >= 4
3432                      || s->aflag == MO_16) {
3433                      goto illegal_op;
3434                  }
3435                  AddressParts a = decode->mem;
3436                  if (a.base >= 0) {
3437                      tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
3438                      if (!CODE64(s)) {
3439                          tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
3440                      }
3441                  } else if (a.base == -1) {
3442                      /* no base register has lower bound of 0 */
3443                      tcg_gen_movi_i64(cpu_bndl[reg], 0);
3444                  } else {
3445                      /* rip-relative generates #ud */
3446                      goto illegal_op;
3447                  }
3448                  tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, decode->mem, false));
3449                  if (!CODE64(s)) {
3450                      tcg_gen_ext32u_tl(s->A0, s->A0);
3451                  }
3452                  tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0);
3453                  /* bnd registers are now in-use */
3454                  gen_set_hflag(s, HF_MPX_IU_MASK);
3455                  break;
3456              } else if (prefixes & PREFIX_REPNZ) {
3457                  /* bndcn */
3458                  if (reg >= 4
3459                      || s->aflag == MO_16) {
3460                      goto illegal_op;
3461                  }
3462                  gen_bndck(s, decode, TCG_COND_GTU, cpu_bndu[reg]);
3463              } else if (prefixes & PREFIX_DATA) {
3464                  /* bndmov -- to reg/mem */
3465                  if (reg >= 4 || s->aflag == MO_16) {
3466                      goto illegal_op;
3467                  }
3468                  if (mod == 3) {
3469                      int reg2 = (modrm & 7) | REX_B(s);
3470                      if (reg2 >= 4) {
3471                          goto illegal_op;
3472                      }
3473                      if (s->flags & HF_MPX_IU_MASK) {
3474                          tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
3475                          tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
3476                      }
3477                  } else {
3478                      gen_lea_modrm(s, decode);
3479                      if (CODE64(s)) {
3480                          tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
3481                                              s->mem_index, MO_LEUQ);
3482                          tcg_gen_addi_tl(s->A0, s->A0, 8);
3483                          tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
3484                                              s->mem_index, MO_LEUQ);
3485                      } else {
3486                          tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
3487                                              s->mem_index, MO_LEUL);
3488                          tcg_gen_addi_tl(s->A0, s->A0, 4);
3489                          tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
3490                                              s->mem_index, MO_LEUL);
3491                      }
3492                  }
3493              } else if (mod != 3) {
3494                  /* bndstx */
3495                  AddressParts a = decode->mem;
3496                  if (reg >= 4
3497                      || s->aflag == MO_16
3498                      || a.base < -1) {
3499                      goto illegal_op;
3500                  }
3501                  if (a.base >= 0) {
3502                      tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
3503                  } else {
3504                      tcg_gen_movi_tl(s->A0, 0);
3505                  }
3506                  gen_lea_v_seg(s, s->A0, a.def_seg, s->override);
3507                  if (a.index >= 0) {
3508                      tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
3509                  } else {
3510                      tcg_gen_movi_tl(s->T0, 0);
3511                  }
3512                  if (CODE64(s)) {
3513                      gen_helper_bndstx64(tcg_env, s->A0, s->T0,
3514                                          cpu_bndl[reg], cpu_bndu[reg]);
3515                  } else {
3516                      gen_helper_bndstx32(tcg_env, s->A0, s->T0,
3517                                          cpu_bndl[reg], cpu_bndu[reg]);
3518                  }
3519              }
3520          }
3521          break;
3522      default:
3523          g_assert_not_reached();
3524      }
3525      return;
3526   illegal_op:
3527      gen_illegal_opcode(s);
3528      return;
3529  }
3530  
3531  #include "decode-new.c.inc"
3532  
tcg_x86_init(void)3533  void tcg_x86_init(void)
3534  {
3535      static const char reg_names[CPU_NB_REGS][4] = {
3536  #ifdef TARGET_X86_64
3537          [R_EAX] = "rax",
3538          [R_EBX] = "rbx",
3539          [R_ECX] = "rcx",
3540          [R_EDX] = "rdx",
3541          [R_ESI] = "rsi",
3542          [R_EDI] = "rdi",
3543          [R_EBP] = "rbp",
3544          [R_ESP] = "rsp",
3545          [8]  = "r8",
3546          [9]  = "r9",
3547          [10] = "r10",
3548          [11] = "r11",
3549          [12] = "r12",
3550          [13] = "r13",
3551          [14] = "r14",
3552          [15] = "r15",
3553  #else
3554          [R_EAX] = "eax",
3555          [R_EBX] = "ebx",
3556          [R_ECX] = "ecx",
3557          [R_EDX] = "edx",
3558          [R_ESI] = "esi",
3559          [R_EDI] = "edi",
3560          [R_EBP] = "ebp",
3561          [R_ESP] = "esp",
3562  #endif
3563      };
3564      static const char eip_name[] = {
3565  #ifdef TARGET_X86_64
3566          "rip"
3567  #else
3568          "eip"
3569  #endif
3570      };
3571      static const char seg_base_names[6][8] = {
3572          [R_CS] = "cs_base",
3573          [R_DS] = "ds_base",
3574          [R_ES] = "es_base",
3575          [R_FS] = "fs_base",
3576          [R_GS] = "gs_base",
3577          [R_SS] = "ss_base",
3578      };
3579      static const char bnd_regl_names[4][8] = {
3580          "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
3581      };
3582      static const char bnd_regu_names[4][8] = {
3583          "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
3584      };
3585      int i;
3586  
3587      cpu_cc_op = tcg_global_mem_new_i32(tcg_env,
3588                                         offsetof(CPUX86State, cc_op), "cc_op");
3589      cpu_cc_dst = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_dst),
3590                                      "cc_dst");
3591      cpu_cc_src = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src),
3592                                      "cc_src");
3593      cpu_cc_src2 = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src2),
3594                                       "cc_src2");
3595      cpu_eip = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, eip), eip_name);
3596  
3597      for (i = 0; i < CPU_NB_REGS; ++i) {
3598          cpu_regs[i] = tcg_global_mem_new(tcg_env,
3599                                           offsetof(CPUX86State, regs[i]),
3600                                           reg_names[i]);
3601      }
3602  
3603      for (i = 0; i < 6; ++i) {
3604          cpu_seg_base[i]
3605              = tcg_global_mem_new(tcg_env,
3606                                   offsetof(CPUX86State, segs[i].base),
3607                                   seg_base_names[i]);
3608      }
3609  
3610      for (i = 0; i < 4; ++i) {
3611          cpu_bndl[i]
3612              = tcg_global_mem_new_i64(tcg_env,
3613                                       offsetof(CPUX86State, bnd_regs[i].lb),
3614                                       bnd_regl_names[i]);
3615          cpu_bndu[i]
3616              = tcg_global_mem_new_i64(tcg_env,
3617                                       offsetof(CPUX86State, bnd_regs[i].ub),
3618                                       bnd_regu_names[i]);
3619      }
3620  }
3621  
i386_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cpu)3622  static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
3623  {
3624      DisasContext *dc = container_of(dcbase, DisasContext, base);
3625      CPUX86State *env = cpu_env(cpu);
3626      uint32_t flags = dc->base.tb->flags;
3627      uint32_t cflags = tb_cflags(dc->base.tb);
3628      int cpl = (flags >> HF_CPL_SHIFT) & 3;
3629      int iopl = (flags >> IOPL_SHIFT) & 3;
3630  
3631      dc->cs_base = dc->base.tb->cs_base;
3632      dc->pc_save = dc->base.pc_next;
3633      dc->flags = flags;
3634  #ifndef CONFIG_USER_ONLY
3635      dc->cpl = cpl;
3636      dc->iopl = iopl;
3637  #endif
3638  
3639      /* We make some simplifying assumptions; validate they're correct. */
3640      g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
3641      g_assert(CPL(dc) == cpl);
3642      g_assert(IOPL(dc) == iopl);
3643      g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
3644      g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
3645      g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0));
3646      g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
3647      g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
3648      g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
3649      g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0));
3650      g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0));
3651  
3652      dc->cc_op = CC_OP_DYNAMIC;
3653      dc->cc_op_dirty = false;
3654      /* select memory access functions */
3655      dc->mem_index = cpu_mmu_index(cpu, false);
3656      dc->cpuid_features = env->features[FEAT_1_EDX];
3657      dc->cpuid_ext_features = env->features[FEAT_1_ECX];
3658      dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
3659      dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
3660      dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
3661      dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX];
3662      dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX];
3663      dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
3664      dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
3665                      (flags & (HF_RF_MASK | HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
3666      /*
3667       * If jmp_opt, we want to handle each string instruction individually.
3668       * For icount also disable repz optimization so that each iteration
3669       * is accounted separately.
3670       *
3671       * FIXME: this is messy; it makes REP string instructions a lot less
3672       * efficient than they should be and it gets in the way of correct
3673       * handling of RF (interrupts or traps arriving after any iteration
3674       * of a repeated string instruction but the last should set RF to 1).
3675       * Perhaps it would be more efficient if REP string instructions were
3676       * always at the beginning of the TB, or even their own TB?  That
3677       * would even allow accounting up to 64k iterations at once for icount.
3678       */
3679      dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT);
3680  
3681      dc->T0 = tcg_temp_new();
3682      dc->T1 = tcg_temp_new();
3683      dc->A0 = tcg_temp_new();
3684  
3685      dc->tmp0 = tcg_temp_new();
3686      dc->tmp1_i64 = tcg_temp_new_i64();
3687      dc->tmp2_i32 = tcg_temp_new_i32();
3688      dc->tmp3_i32 = tcg_temp_new_i32();
3689      dc->tmp4 = tcg_temp_new();
3690      dc->cc_srcT = tcg_temp_new();
3691  }
3692  
i386_tr_tb_start(DisasContextBase * db,CPUState * cpu)3693  static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
3694  {
3695  }
3696  
i386_tr_insn_start(DisasContextBase * dcbase,CPUState * cpu)3697  static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
3698  {
3699      DisasContext *dc = container_of(dcbase, DisasContext, base);
3700      target_ulong pc_arg = dc->base.pc_next;
3701  
3702      dc->prev_insn_start = dc->base.insn_start;
3703      dc->prev_insn_end = tcg_last_op();
3704      if (tb_cflags(dcbase->tb) & CF_PCREL) {
3705          pc_arg &= ~TARGET_PAGE_MASK;
3706      }
3707      tcg_gen_insn_start(pc_arg, dc->cc_op);
3708  }
3709  
i386_tr_translate_insn(DisasContextBase * dcbase,CPUState * cpu)3710  static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
3711  {
3712      DisasContext *dc = container_of(dcbase, DisasContext, base);
3713      bool orig_cc_op_dirty = dc->cc_op_dirty;
3714      CCOp orig_cc_op = dc->cc_op;
3715      target_ulong orig_pc_save = dc->pc_save;
3716  
3717  #ifdef TARGET_VSYSCALL_PAGE
3718      /*
3719       * Detect entry into the vsyscall page and invoke the syscall.
3720       */
3721      if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) {
3722          gen_exception(dc, EXCP_VSYSCALL);
3723          dc->base.pc_next = dc->pc + 1;
3724          return;
3725      }
3726  #endif
3727  
3728      switch (sigsetjmp(dc->jmpbuf, 0)) {
3729      case 0:
3730          disas_insn(dc, cpu);
3731          break;
3732      case 1:
3733          gen_exception_gpf(dc);
3734          break;
3735      case 2:
3736          /* Restore state that may affect the next instruction. */
3737          dc->pc = dc->base.pc_next;
3738          assert(dc->cc_op_dirty == orig_cc_op_dirty);
3739          assert(dc->cc_op == orig_cc_op);
3740          assert(dc->pc_save == orig_pc_save);
3741          dc->base.num_insns--;
3742          tcg_remove_ops_after(dc->prev_insn_end);
3743          dc->base.insn_start = dc->prev_insn_start;
3744          dc->base.is_jmp = DISAS_TOO_MANY;
3745          return;
3746      default:
3747          g_assert_not_reached();
3748      }
3749  
3750      /*
3751       * Instruction decoding completed (possibly with #GP if the
3752       * 15-byte boundary was exceeded).
3753       */
3754      dc->base.pc_next = dc->pc;
3755      if (dc->base.is_jmp == DISAS_NEXT) {
3756          if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
3757              /*
3758               * If single step mode, we generate only one instruction and
3759               * generate an exception.
3760               * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
3761               * the flag and abort the translation to give the irqs a
3762               * chance to happen.
3763               */
3764              dc->base.is_jmp = DISAS_EOB_NEXT;
3765          } else if (!is_same_page(&dc->base, dc->base.pc_next)) {
3766              dc->base.is_jmp = DISAS_TOO_MANY;
3767          }
3768      }
3769  }
3770  
i386_tr_tb_stop(DisasContextBase * dcbase,CPUState * cpu)3771  static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
3772  {
3773      DisasContext *dc = container_of(dcbase, DisasContext, base);
3774  
3775      switch (dc->base.is_jmp) {
3776      case DISAS_NORETURN:
3777          /*
3778           * Most instructions should not use DISAS_NORETURN, as that suppresses
3779           * the handling of hflags normally done by gen_eob().  We can
3780           * get here:
3781           * - for exception and interrupts
3782           * - for jump optimization (which is disabled by INHIBIT_IRQ/RF/TF)
3783           * - for VMRUN because RF/TF handling for the host is done after vmexit,
3784           *   and INHIBIT_IRQ is loaded from the VMCB
3785           * - for HLT/PAUSE/MWAIT to exit the main loop with specific EXCP_* values;
3786           *   the helpers handle themselves the tasks normally done by gen_eob().
3787           */
3788          break;
3789      case DISAS_TOO_MANY:
3790          gen_update_cc_op(dc);
3791          gen_jmp_rel_csize(dc, 0, 0);
3792          break;
3793      case DISAS_EOB_NEXT:
3794      case DISAS_EOB_INHIBIT_IRQ:
3795          assert(dc->base.pc_next == dc->pc);
3796          gen_update_eip_cur(dc);
3797          /* fall through */
3798      case DISAS_EOB_ONLY:
3799      case DISAS_EOB_RECHECK_TF:
3800      case DISAS_JUMP:
3801          gen_eob(dc, dc->base.is_jmp);
3802          break;
3803      default:
3804          g_assert_not_reached();
3805      }
3806  }
3807  
3808  static const TranslatorOps i386_tr_ops = {
3809      .init_disas_context = i386_tr_init_disas_context,
3810      .tb_start           = i386_tr_tb_start,
3811      .insn_start         = i386_tr_insn_start,
3812      .translate_insn     = i386_tr_translate_insn,
3813      .tb_stop            = i386_tr_tb_stop,
3814  };
3815  
3816  /* generate intermediate code for basic block 'tb'.  */
gen_intermediate_code(CPUState * cpu,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)3817  void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
3818                             vaddr pc, void *host_pc)
3819  {
3820      DisasContext dc;
3821  
3822      translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base);
3823  }
3824