• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   *  i386 translation
3   *
4   *  Copyright (c) 2003 Fabrice Bellard
5   *
6   * This library is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU Lesser General Public
8   * License as published by the Free Software Foundation; either
9   * version 2 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18   */
19  #include <stdarg.h>
20  #include <stdlib.h>
21  #include <stdio.h>
22  #include <string.h>
23  #include <inttypes.h>
24  #include <signal.h>
25  
26  #include "qemu/host-utils.h"
27  #include "cpu.h"
28  #include "disas/disas.h"
29  #include "tcg-op.h"
30  
31  #include "helper.h"
32  #define GEN_HELPER 1
33  #include "helper.h"
34  #include "exec/hax.h"
35  
36  #ifdef _WIN32
37  #undef grp2
38  #endif
39  
40  #define PREFIX_REPZ   0x01
41  #define PREFIX_REPNZ  0x02
42  #define PREFIX_LOCK   0x04
43  #define PREFIX_DATA   0x08
44  #define PREFIX_ADR    0x10
45  #define PREFIX_VEX    0x20
46  
47  #ifdef TARGET_X86_64
48  #define X86_64_ONLY(x) x
49  #define X86_64_DEF(...)  __VA_ARGS__
50  #define CODE64(s) ((s)->code64)
51  #define REX_X(s) ((s)->rex_x)
52  #define REX_B(s) ((s)->rex_b)
53  /* XXX: gcc generates push/pop in some opcodes, so we cannot use them */
54  #if 1
55  #define BUGGY_64(x) NULL
56  #endif
57  #else
58  #define X86_64_ONLY(x) NULL
59  #define X86_64_DEF(...)
60  #define CODE64(s) 0
61  #define REX_X(s) 0
62  #define REX_B(s) 0
63  #endif
64  
65  #ifdef TARGET_X86_64
66  # define ctztl  ctz64
67  # define clztl  clz64
68  #else
69  # define ctztl  ctz32
70  # define clztl  clz32
71  #endif
72  
73  //#define MACRO_TEST   1
74  
75  /* global register indexes */
76  static TCGv_ptr cpu_env;
77  static TCGv cpu_A0, cpu_cc_src, cpu_cc_dst;
78  static TCGv_i32 cpu_cc_op;
79  /* local temps */
80  static TCGv cpu_T[2], cpu_T3;
81  /* local register indexes (only used inside old micro ops) */
82  static TCGv cpu_tmp0, cpu_tmp4;
83  static TCGv_ptr cpu_ptr0, cpu_ptr1;
84  static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
85  static TCGv_i64 cpu_tmp1_i64;
86  static TCGv cpu_tmp5, cpu_tmp6;
87  
88  static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
89  
90  #include "exec/gen-icount.h"
91  
92  #ifdef TARGET_X86_64
93  static int x86_64_hregs;
94  #endif
95  
96  typedef struct DisasContext {
97      /* current insn context */
98      int override; /* -1 if no override */
99      int prefix;
100      int aflag, dflag;
101      target_ulong pc; /* pc = eip + cs_base */
102      int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
103                     static state change (stop translation) */
104      /* current block context */
105      target_ulong cs_base; /* base of CS segment */
106      int pe;     /* protected mode */
107      int code32; /* 32 bit code segment */
108  #ifdef TARGET_X86_64
109      int lma;    /* long mode active */
110      int code64; /* 64 bit code segment */
111      int rex_x, rex_b;
112  #endif
113      int ss32;   /* 32 bit stack segment */
114      CCOp cc_op;  /* current CC operation */
115      bool cc_op_dirty;
116      int addseg; /* non zero if either DS/ES/SS have a non zero base */
117      int f_st;   /* currently unused */
118      int vm86;   /* vm86 mode */
119      int cpl;
120      int iopl;
121      int tf;     /* TF cpu flag */
122      int singlestep_enabled; /* "hardware" single step enabled */
123      int jmp_opt; /* use direct block chaining for direct jumps */
124      int mem_index; /* select memory access functions */
125      uint64_t flags; /* all execution flags */
126      struct TranslationBlock *tb;
127      int popl_esp_hack; /* for correct popl with esp base handling */
128      int rip_offset; /* only used in x86_64, but left for simplicity */
129      int cpuid_features;
130      int cpuid_ext_features;
131      int cpuid_ext2_features;
132      int cpuid_ext3_features;
133  } DisasContext;
134  
135  static void gen_eob(DisasContext *s);
136  static void gen_jmp(DisasContext *s, target_ulong eip);
137  static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
138  
139  /* i386 arith/logic operations */
140  enum {
141      OP_ADDL,
142      OP_ORL,
143      OP_ADCL,
144      OP_SBBL,
145      OP_ANDL,
146      OP_SUBL,
147      OP_XORL,
148      OP_CMPL,
149  };
150  
151  /* i386 shift ops */
152  enum {
153      OP_ROL,
154      OP_ROR,
155      OP_RCL,
156      OP_RCR,
157      OP_SHL,
158      OP_SHR,
159      OP_SHL1, /* undocumented */
160      OP_SAR = 7,
161  };
162  
163  enum {
164      JCC_O,
165      JCC_B,
166      JCC_Z,
167      JCC_BE,
168      JCC_S,
169      JCC_P,
170      JCC_L,
171      JCC_LE,
172  };
173  
174  /* operand size */
175  enum {
176      OT_BYTE = 0,
177      OT_WORD,
178      OT_LONG,
179      OT_QUAD,
180  };
181  
182  enum {
183      /* I386 int registers */
184      OR_EAX,   /* MUST be even numbered */
185      OR_ECX,
186      OR_EDX,
187      OR_EBX,
188      OR_ESP,
189      OR_EBP,
190      OR_ESI,
191      OR_EDI,
192  
193      OR_TMP0 = 16,    /* temporary operand register */
194      OR_TMP1,
195      OR_A0, /* temporary register used when doing address evaluation */
196  };
197  
198  enum {
199      USES_CC_DST = 1,
200      USES_CC_SRC = 2,
201  };
202  
203  /* Bit set if the global variable is live after setting CC_OP to X.  */
204  static const uint8_t cc_op_live[CC_OP_NB] = {
205      [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC,
206      [CC_OP_EFLAGS] = USES_CC_SRC,
207      [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
208      [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
209      [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC,
210      [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC,
211      [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC,
212      [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
213      [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
214      [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
215      [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
216      [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
217  };
218  
set_cc_op(DisasContext * s,CCOp op)219  static void set_cc_op(DisasContext *s, CCOp op)
220  {
221      int dead;
222  
223      if (s->cc_op == op) {
224          return;
225      }
226  
227      /* Discard CC computation that will no longer be used.  */
228      dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
229      if (dead & USES_CC_DST) {
230          tcg_gen_discard_tl(cpu_cc_dst);
231      }
232      if (dead & USES_CC_SRC) {
233          tcg_gen_discard_tl(cpu_cc_src);
234      }
235  
236      s->cc_op = op;
237      /* The DYNAMIC setting is translator only, and should never be
238         stored.  Thus we always consider it clean.  */
239      s->cc_op_dirty = (op != CC_OP_DYNAMIC);
240  }
241  
gen_update_cc_op(DisasContext * s)242  static void gen_update_cc_op(DisasContext *s)
243  {
244      if (s->cc_op_dirty) {
245          tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
246          s->cc_op_dirty = false;
247      }
248  }
249  
gen_op_movl_T0_0(void)250  static inline void gen_op_movl_T0_0(void)
251  {
252      tcg_gen_movi_tl(cpu_T[0], 0);
253  }
254  
gen_op_movl_T0_im(int32_t val)255  static inline void gen_op_movl_T0_im(int32_t val)
256  {
257      tcg_gen_movi_tl(cpu_T[0], val);
258  }
259  
gen_op_movl_T0_imu(uint32_t val)260  static inline void gen_op_movl_T0_imu(uint32_t val)
261  {
262      tcg_gen_movi_tl(cpu_T[0], val);
263  }
264  
gen_op_movl_T1_im(int32_t val)265  static inline void gen_op_movl_T1_im(int32_t val)
266  {
267      tcg_gen_movi_tl(cpu_T[1], val);
268  }
269  
gen_op_movl_T1_imu(uint32_t val)270  static inline void gen_op_movl_T1_imu(uint32_t val)
271  {
272      tcg_gen_movi_tl(cpu_T[1], val);
273  }
274  
gen_op_movl_A0_im(uint32_t val)275  static inline void gen_op_movl_A0_im(uint32_t val)
276  {
277      tcg_gen_movi_tl(cpu_A0, val);
278  }
279  
280  #ifdef TARGET_X86_64
gen_op_movq_A0_im(int64_t val)281  static inline void gen_op_movq_A0_im(int64_t val)
282  {
283      tcg_gen_movi_tl(cpu_A0, val);
284  }
285  #endif
286  
gen_movtl_T0_im(target_ulong val)287  static inline void gen_movtl_T0_im(target_ulong val)
288  {
289      tcg_gen_movi_tl(cpu_T[0], val);
290  }
291  
gen_movtl_T1_im(target_ulong val)292  static inline void gen_movtl_T1_im(target_ulong val)
293  {
294      tcg_gen_movi_tl(cpu_T[1], val);
295  }
296  
gen_op_andl_T0_ffff(void)297  static inline void gen_op_andl_T0_ffff(void)
298  {
299      tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
300  }
301  
gen_op_andl_T0_im(uint32_t val)302  static inline void gen_op_andl_T0_im(uint32_t val)
303  {
304      tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
305  }
306  
gen_op_movl_T0_T1(void)307  static inline void gen_op_movl_T0_T1(void)
308  {
309      tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
310  }
311  
gen_op_andl_A0_ffff(void)312  static inline void gen_op_andl_A0_ffff(void)
313  {
314      tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
315  }
316  
317  #ifdef TARGET_X86_64
318  
319  #define NB_OP_SIZES 4
320  
321  #else /* !TARGET_X86_64 */
322  
323  #define NB_OP_SIZES 3
324  
325  #endif /* !TARGET_X86_64 */
326  
327  #if defined(WORDS_BIGENDIAN)
328  #define REG_B_OFFSET (sizeof(target_ulong) - 1)
329  #define REG_H_OFFSET (sizeof(target_ulong) - 2)
330  #define REG_W_OFFSET (sizeof(target_ulong) - 2)
331  #define REG_L_OFFSET (sizeof(target_ulong) - 4)
332  #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
333  #else
334  #define REG_B_OFFSET 0
335  #define REG_H_OFFSET 1
336  #define REG_W_OFFSET 0
337  #define REG_L_OFFSET 0
338  #define REG_LH_OFFSET 4
339  #endif
340  
341  /* In instruction encodings for byte register accesses the
342   * register number usually indicates "low 8 bits of register N";
343   * however there are some special cases where N 4..7 indicates
344   * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
345   * true for this special case, false otherwise.
346   */
byte_reg_is_xH(int reg)347  static inline bool byte_reg_is_xH(int reg)
348  {
349      if (reg < 4) {
350          return false;
351      }
352  #ifdef TARGET_X86_64
353      if (reg >= 8 || x86_64_hregs) {
354          return false;
355      }
356  #endif
357      return true;
358  }
359  
gen_op_mov_reg_v(int ot,int reg,TCGv t0)360  static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
361  {
362      switch(ot) {
363      case OT_BYTE:
364          if (!byte_reg_is_xH(reg)) {
365              tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_B_OFFSET);
366          } else {
367              tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg - 4]) + REG_H_OFFSET);
368          }
369          break;
370      case OT_WORD:
371          tcg_gen_st16_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET);
372          break;
373  #ifdef TARGET_X86_64
374      case OT_LONG:
375          tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
376          /* high part of register set to zero */
377          tcg_gen_movi_tl(cpu_tmp0, 0);
378          tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_LH_OFFSET);
379          break;
380      default:
381      case OT_QUAD:
382          tcg_gen_st_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]));
383          break;
384  #else
385      default:
386      case OT_LONG:
387          tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
388          break;
389  #endif
390      }
391  }
392  
gen_op_mov_reg_T0(int ot,int reg)393  static inline void gen_op_mov_reg_T0(int ot, int reg)
394  {
395      gen_op_mov_reg_v(ot, reg, cpu_T[0]);
396  }
397  
gen_op_mov_reg_T1(int ot,int reg)398  static inline void gen_op_mov_reg_T1(int ot, int reg)
399  {
400      gen_op_mov_reg_v(ot, reg, cpu_T[1]);
401  }
402  
gen_op_mov_reg_A0(int size,int reg)403  static inline void gen_op_mov_reg_A0(int size, int reg)
404  {
405      switch(size) {
406      case OT_BYTE:
407          tcg_gen_st16_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET);
408          break;
409  #ifdef TARGET_X86_64
410      case OT_WORD:
411          tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
412          /* high part of register set to zero */
413          tcg_gen_movi_tl(cpu_tmp0, 0);
414          tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_LH_OFFSET);
415          break;
416      default:
417      case OT_LONG:
418          tcg_gen_st_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]));
419          break;
420  #else
421      default:
422      case OT_WORD:
423          tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
424          break;
425  #endif
426      }
427  }
428  
gen_op_mov_v_reg(int ot,TCGv t0,int reg)429  static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
430  {
431      if (ot == OT_BYTE && byte_reg_is_xH(reg)) {
432          tcg_gen_ld8u_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg - 4]) + REG_H_OFFSET);
433      } else {
434          tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]));
435      }
436  }
437  
gen_op_mov_TN_reg(int ot,int t_index,int reg)438  static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
439  {
440      gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
441  }
442  
gen_op_movl_A0_reg(int reg)443  static inline void gen_op_movl_A0_reg(int reg)
444  {
445      tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
446  }
447  
gen_op_addl_A0_im(int32_t val)448  static inline void gen_op_addl_A0_im(int32_t val)
449  {
450      tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
451  #ifdef TARGET_X86_64
452      tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
453  #endif
454  }
455  
456  #ifdef TARGET_X86_64
gen_op_addq_A0_im(int64_t val)457  static inline void gen_op_addq_A0_im(int64_t val)
458  {
459      tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
460  }
461  #endif
462  
gen_add_A0_im(DisasContext * s,int val)463  static void gen_add_A0_im(DisasContext *s, int val)
464  {
465  #ifdef TARGET_X86_64
466      if (CODE64(s))
467          gen_op_addq_A0_im(val);
468      else
469  #endif
470          gen_op_addl_A0_im(val);
471  }
472  
gen_op_addl_T0_T1(void)473  static inline void gen_op_addl_T0_T1(void)
474  {
475      tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
476  }
477  
gen_op_jmp_T0(void)478  static inline void gen_op_jmp_T0(void)
479  {
480      tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, eip));
481  }
482  
gen_op_add_reg_im(int size,int reg,int32_t val)483  static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
484  {
485      switch(size) {
486      case OT_BYTE:
487          tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
488          tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
489          tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET);
490          break;
491      case OT_WORD:
492          tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
493          tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
494  #ifdef TARGET_X86_64
495          tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
496  #endif
497          tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
498          break;
499  #ifdef TARGET_X86_64
500      case OT_LONG:
501          tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
502          tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
503          tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
504          break;
505  #endif
506      }
507  }
508  
gen_op_add_reg_T0(int size,int reg)509  static inline void gen_op_add_reg_T0(int size, int reg)
510  {
511      switch(size) {
512      case OT_BYTE:
513          tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
514          tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
515          tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET);
516          break;
517      case OT_WORD:
518          tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
519          tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
520  #ifdef TARGET_X86_64
521          tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
522  #endif
523          tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
524          break;
525  #ifdef TARGET_X86_64
526      case OT_LONG:
527          tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
528          tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]);
529          tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
530          break;
531  #endif
532      }
533  }
534  
gen_op_addl_A0_reg_sN(int shift,int reg)535  static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
536  {
537      tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
538      if (shift != 0)
539          tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
540      tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
541  #ifdef TARGET_X86_64
542      tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
543  #endif
544  }
545  
gen_op_movl_A0_seg(int reg)546  static inline void gen_op_movl_A0_seg(int reg)
547  {
548      tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base) + REG_L_OFFSET);
549  }
550  
gen_op_addl_A0_seg(DisasContext * s,int reg)551  static inline void gen_op_addl_A0_seg(DisasContext *s, int reg)
552  {
553      tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
554      tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
555  #ifdef TARGET_X86_64
556      tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
557  #endif
558  }
559  
560  #ifdef TARGET_X86_64
gen_op_movq_A0_seg(int reg)561  static inline void gen_op_movq_A0_seg(int reg)
562  {
563      tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base));
564  }
565  
gen_op_addq_A0_seg(int reg)566  static inline void gen_op_addq_A0_seg(int reg)
567  {
568      tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
569      tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
570  }
571  
gen_op_movq_A0_reg(int reg)572  static inline void gen_op_movq_A0_reg(int reg)
573  {
574      tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]));
575  }
576  
gen_op_addq_A0_reg_sN(int shift,int reg)577  static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
578  {
579      tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]));
580      if (shift != 0)
581          tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
582      tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
583  }
584  #endif
585  
gen_op_lds_T0_A0(int idx)586  static inline void gen_op_lds_T0_A0(int idx)
587  {
588      int mem_index = (idx >> 2) - 1;
589      switch(idx & 3) {
590      case OT_BYTE:
591          tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index);
592          break;
593      case OT_WORD:
594          tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index);
595          break;
596      default:
597      case OT_LONG:
598          tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index);
599          break;
600      }
601  }
602  
gen_op_ld_v(int idx,TCGv t0,TCGv a0)603  static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0)
604  {
605      int mem_index = (idx >> 2) - 1;
606      switch(idx & 3) {
607      case OT_BYTE:
608          tcg_gen_qemu_ld8u(t0, a0, mem_index);
609          break;
610      case OT_WORD:
611          tcg_gen_qemu_ld16u(t0, a0, mem_index);
612          break;
613      case OT_LONG:
614          tcg_gen_qemu_ld32u(t0, a0, mem_index);
615          break;
616      default:
617      case OT_QUAD:
618          /* Should never happen on 32-bit targets.  */
619  #ifdef TARGET_X86_64
620          tcg_gen_qemu_ld64(t0, a0, mem_index);
621  #endif
622          break;
623      }
624  }
625  
626  /* XXX: always use ldu or lds */
gen_op_ld_T0_A0(int idx)627  static inline void gen_op_ld_T0_A0(int idx)
628  {
629      gen_op_ld_v(idx, cpu_T[0], cpu_A0);
630  }
631  
gen_op_ldu_T0_A0(int idx)632  static inline void gen_op_ldu_T0_A0(int idx)
633  {
634      gen_op_ld_v(idx, cpu_T[0], cpu_A0);
635  }
636  
gen_op_ld_T1_A0(int idx)637  static inline void gen_op_ld_T1_A0(int idx)
638  {
639      gen_op_ld_v(idx, cpu_T[1], cpu_A0);
640  }
641  
gen_op_st_v(int idx,TCGv t0,TCGv a0)642  static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0)
643  {
644      int mem_index = (idx >> 2) - 1;
645      switch(idx & 3) {
646      case OT_BYTE:
647          tcg_gen_qemu_st8(t0, a0, mem_index);
648          break;
649      case OT_WORD:
650          tcg_gen_qemu_st16(t0, a0, mem_index);
651          break;
652      case OT_LONG:
653          tcg_gen_qemu_st32(t0, a0, mem_index);
654          break;
655      default:
656      case OT_QUAD:
657          /* Should never happen on 32-bit targets.  */
658  #ifdef TARGET_X86_64
659          tcg_gen_qemu_st64(t0, a0, mem_index);
660  #endif
661          break;
662      }
663  }
664  
gen_op_st_T0_A0(int idx)665  static inline void gen_op_st_T0_A0(int idx)
666  {
667      gen_op_st_v(idx, cpu_T[0], cpu_A0);
668  }
669  
gen_op_st_T1_A0(int idx)670  static inline void gen_op_st_T1_A0(int idx)
671  {
672      gen_op_st_v(idx, cpu_T[1], cpu_A0);
673  }
674  
gen_jmp_im(target_ulong pc)675  static inline void gen_jmp_im(target_ulong pc)
676  {
677      tcg_gen_movi_tl(cpu_tmp0, pc);
678      tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, eip));
679  }
680  
gen_string_movl_A0_ESI(DisasContext * s)681  static inline void gen_string_movl_A0_ESI(DisasContext *s)
682  {
683      int override;
684  
685      override = s->override;
686  #ifdef TARGET_X86_64
687      if (s->aflag == 2) {
688          if (override >= 0) {
689              gen_op_movq_A0_seg(override);
690              gen_op_addq_A0_reg_sN(0, R_ESI);
691          } else {
692              gen_op_movq_A0_reg(R_ESI);
693          }
694      } else
695  #endif
696      if (s->aflag) {
697          /* 32 bit address */
698          if (s->addseg && override < 0)
699              override = R_DS;
700          if (override >= 0) {
701              gen_op_movl_A0_seg(override);
702              gen_op_addl_A0_reg_sN(0, R_ESI);
703          } else {
704              gen_op_movl_A0_reg(R_ESI);
705          }
706      } else {
707          /* 16 address, always override */
708          if (override < 0)
709              override = R_DS;
710          gen_op_movl_A0_reg(R_ESI);
711          gen_op_andl_A0_ffff();
712          gen_op_addl_A0_seg(s, override);
713      }
714  }
715  
gen_string_movl_A0_EDI(DisasContext * s)716  static inline void gen_string_movl_A0_EDI(DisasContext *s)
717  {
718  #ifdef TARGET_X86_64
719      if (s->aflag == 2) {
720          gen_op_movq_A0_reg(R_EDI);
721      } else
722  #endif
723      if (s->aflag) {
724          if (s->addseg) {
725              gen_op_movl_A0_seg(R_ES);
726              gen_op_addl_A0_reg_sN(0, R_EDI);
727          } else {
728              gen_op_movl_A0_reg(R_EDI);
729          }
730      } else {
731          gen_op_movl_A0_reg(R_EDI);
732          gen_op_andl_A0_ffff();
733          gen_op_addl_A0_seg(s, R_ES);
734      }
735  }
736  
gen_op_movl_T0_Dshift(int ot)737  static inline void gen_op_movl_T0_Dshift(int ot)
738  {
739      tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, df));
740      tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
741  };
742  
gen_ext_tl(TCGv dst,TCGv src,int size,bool sign)743  static TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign)
744  {
745      switch (size) {
746      case OT_BYTE:
747          if (sign) {
748              tcg_gen_ext8s_tl(dst, src);
749          } else {
750              tcg_gen_ext8u_tl(dst, src);
751          }
752          return dst;
753      case OT_WORD:
754          if (sign) {
755              tcg_gen_ext16s_tl(dst, src);
756          } else {
757              tcg_gen_ext16u_tl(dst, src);
758          }
759          return dst;
760  #ifdef TARGET_X86_64
761      case OT_LONG:
762          if (sign) {
763              tcg_gen_ext32s_tl(dst, src);
764          } else {
765              tcg_gen_ext32u_tl(dst, src);
766          }
767          return dst;
768  #endif
769      default:
770          return src;
771      }
772  }
773  
gen_extu(int ot,TCGv reg)774  static void gen_extu(int ot, TCGv reg)
775  {
776      gen_ext_tl(reg, reg, ot, false);
777  }
778  
gen_exts(int ot,TCGv reg)779  static void gen_exts(int ot, TCGv reg)
780  {
781      gen_ext_tl(reg, reg, ot, true);
782  }
783  
gen_op_jnz_ecx(int size,int label1)784  static inline void gen_op_jnz_ecx(int size, int label1)
785  {
786      tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[R_ECX]));
787      gen_extu(size + 1, cpu_tmp0);
788      tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
789  }
790  
gen_op_jz_ecx(int size,int label1)791  static inline void gen_op_jz_ecx(int size, int label1)
792  {
793      tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[R_ECX]));
794      gen_extu(size + 1, cpu_tmp0);
795      tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
796  }
797  
gen_helper_in_func(int ot,TCGv v,TCGv_i32 n)798  static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n)
799  {
800      switch (ot) {
801      case OT_BYTE:
802          gen_helper_inb(v, n);
803          break;
804      case OT_WORD:
805          gen_helper_inw(v, n);
806          break;
807      case OT_LONG:
808          gen_helper_inl(v, n);
809          break;
810      }
811  }
812  
gen_helper_out_func(int ot,TCGv_i32 v,TCGv_i32 n)813  static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n)
814  {
815      switch (ot) {
816      case OT_BYTE:
817          gen_helper_outb(v, n);
818          break;
819      case OT_WORD:
820          gen_helper_outw(v, n);
821          break;
822      case OT_LONG:
823          gen_helper_outl(v, n);
824          break;
825      }
826  }
827  
gen_check_io(DisasContext * s,int ot,target_ulong cur_eip,uint32_t svm_flags)828  static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
829                           uint32_t svm_flags)
830  {
831      int state_saved;
832      target_ulong next_eip;
833  
834      state_saved = 0;
835      if (s->pe && (s->cpl > s->iopl || s->vm86)) {
836          gen_update_cc_op(s);
837          gen_jmp_im(cur_eip);
838          state_saved = 1;
839          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
840          switch (ot) {
841          case OT_BYTE:
842              gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
843              break;
844          case OT_WORD:
845              gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
846              break;
847          case OT_LONG:
848              gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
849              break;
850          }
851      }
852      if(s->flags & HF_SVMI_MASK) {
853          if (!state_saved) {
854              gen_update_cc_op(s);
855              gen_jmp_im(cur_eip);
856              state_saved = 1;
857          }
858          svm_flags |= (1 << (4 + ot));
859          next_eip = s->pc - s->cs_base;
860          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
861          gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
862                                  tcg_const_i32(svm_flags),
863                                  tcg_const_i32(next_eip - cur_eip));
864      }
865  }
866  
gen_movs(DisasContext * s,int ot)867  static inline void gen_movs(DisasContext *s, int ot)
868  {
869      gen_string_movl_A0_ESI(s);
870      gen_op_ld_T0_A0(ot + s->mem_index);
871      gen_string_movl_A0_EDI(s);
872      gen_op_st_T0_A0(ot + s->mem_index);
873      gen_op_movl_T0_Dshift(ot);
874      gen_op_add_reg_T0(s->aflag, R_ESI);
875      gen_op_add_reg_T0(s->aflag, R_EDI);
876  }
877  
gen_op_update1_cc(void)878  static void gen_op_update1_cc(void)
879  {
880      tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
881  }
882  
gen_op_update2_cc(void)883  static void gen_op_update2_cc(void)
884  {
885      tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
886      tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
887  }
888  
gen_op_cmpl_T0_T1_cc(void)889  static inline void gen_op_cmpl_T0_T1_cc(void)
890  {
891      tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
892      tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
893  }
894  
gen_op_testl_T0_T1_cc(void)895  static inline void gen_op_testl_T0_T1_cc(void)
896  {
897      tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
898  }
899  
gen_op_update_neg_cc(void)900  static void gen_op_update_neg_cc(void)
901  {
902      tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
903      tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
904  }
905  
906  /* compute all eflags to cc_src */
gen_compute_eflags(DisasContext * s)907  static void gen_compute_eflags(DisasContext *s)
908  {
909      if (s->cc_op == CC_OP_EFLAGS) {
910          return;
911      }
912      gen_update_cc_op(s);
913      gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_env, cpu_cc_op);
914      set_cc_op(s, CC_OP_EFLAGS);
915      tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
916  }
917  
918  /* compute eflags.C to reg */
gen_compute_eflags_c(DisasContext * s,TCGv reg,bool inv)919  static void gen_compute_eflags_c(DisasContext *s, TCGv reg, bool inv)
920  {
921      TCGv t0, t1;
922      int size;
923  
924      switch (s->cc_op) {
925      case CC_OP_SUBB ... CC_OP_SUBQ:
926          /* (DATA_TYPE)(CC_DST + CC_SRC) < (DATA_TYPE)CC_SRC */
927          size = s->cc_op - CC_OP_SUBB;
928          t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
929          /* If no temporary was used, be careful not to alias t1 and t0.  */
930          t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;
931          tcg_gen_add_tl(t0, cpu_cc_dst, cpu_cc_src);
932          gen_extu(size, t0);
933          goto add_sub;
934  
935      case CC_OP_ADDB ... CC_OP_ADDQ:
936          /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
937          size = s->cc_op - CC_OP_ADDB;
938          t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
939          t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
940      add_sub:
941          tcg_gen_setcond_tl(inv ? TCG_COND_GEU : TCG_COND_LTU, reg, t0, t1);
942          inv = false;
943          break;
944  
945      case CC_OP_SBBB ... CC_OP_SBBQ:
946          /* (DATA_TYPE)(CC_DST + CC_SRC + 1) <= (DATA_TYPE)CC_SRC */
947          size = s->cc_op - CC_OP_SBBB;
948          t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
949          if (TCGV_EQUAL(t1, reg) && TCGV_EQUAL(reg, cpu_cc_src)) {
950              tcg_gen_mov_tl(cpu_tmp0, cpu_cc_src);
951              t1 = cpu_tmp0;
952          }
953  
954          tcg_gen_add_tl(reg, cpu_cc_dst, cpu_cc_src);
955          tcg_gen_addi_tl(reg, reg, 1);
956          gen_extu(size, reg);
957          t0 = reg;
958          goto adc_sbb;
959  
960      case CC_OP_ADCB ... CC_OP_ADCQ:
961          /* (DATA_TYPE)CC_DST <= (DATA_TYPE)CC_SRC */
962          size = s->cc_op - CC_OP_ADCB;
963          t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
964          t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
965      adc_sbb:
966          tcg_gen_setcond_tl(inv ? TCG_COND_GTU : TCG_COND_LEU, reg, t0, t1);
967          inv = false;
968          break;
969  
970      case CC_OP_LOGICB ... CC_OP_LOGICQ:
971          tcg_gen_movi_tl(reg, 0);
972          break;
973  
974      case CC_OP_INCB ... CC_OP_INCQ:
975      case CC_OP_DECB ... CC_OP_DECQ:
976          if (inv) {
977              tcg_gen_xori_tl(reg, cpu_cc_src, 1);
978          } else {
979              tcg_gen_mov_tl(reg, cpu_cc_src);
980          }
981          inv = false;
982          break;
983  
984      case CC_OP_SHLB ... CC_OP_SHLQ:
985          /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
986          size = s->cc_op - CC_OP_SHLB;
987          tcg_gen_shri_tl(reg, cpu_cc_src, (8 << size) - 1);
988          tcg_gen_andi_tl(reg, reg, 1);
989          break;
990  
991      case CC_OP_MULB ... CC_OP_MULQ:
992          tcg_gen_setcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE,
993                              reg, cpu_cc_src, 0);
994          inv = false;
995          break;
996  
997      case CC_OP_EFLAGS:
998      case CC_OP_SARB ... CC_OP_SARQ:
999          /* CC_SRC & 1 */
1000          tcg_gen_andi_tl(reg, cpu_cc_src, 1);
1001          break;
1002  
1003      default:
1004         /* The need to compute only C from CC_OP_DYNAMIC is important
1005            in efficiently implementing e.g. INC at the start of a TB.  */
1006         gen_update_cc_op(s);
1007         gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_env, cpu_cc_op);
1008         tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
1009         break;
1010      }
1011      if (inv) {
1012          tcg_gen_xori_tl(reg, reg, 1);
1013      }
1014  }
1015  
1016  /* compute eflags.P to reg */
gen_compute_eflags_p(DisasContext * s,TCGv reg)1017  static void gen_compute_eflags_p(DisasContext *s, TCGv reg)
1018  {
1019      gen_compute_eflags(s);
1020      tcg_gen_shri_tl(reg, cpu_cc_src, 2);
1021      tcg_gen_andi_tl(reg, reg, 1);
1022  }
1023  
1024  /* compute eflags.S to reg */
gen_compute_eflags_s(DisasContext * s,TCGv reg,bool inv)1025  static void gen_compute_eflags_s(DisasContext *s, TCGv reg, bool inv)
1026  {
1027      switch (s->cc_op) {
1028      case CC_OP_DYNAMIC:
1029          gen_compute_eflags(s);
1030          /* FALLTHRU */
1031      case CC_OP_EFLAGS:
1032          tcg_gen_shri_tl(reg, cpu_cc_src, 7);
1033          tcg_gen_andi_tl(reg, reg, 1);
1034          if (inv) {
1035              tcg_gen_xori_tl(reg, reg, 1);
1036          }
1037          break;
1038      default:
1039          {
1040              int size = (s->cc_op - CC_OP_ADDB) & 3;
1041              TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
1042              tcg_gen_setcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, reg, t0, 0);
1043          }
1044          break;
1045      }
1046  }
1047  
1048  /* compute eflags.O to reg */
gen_compute_eflags_o(DisasContext * s,TCGv reg)1049  static void gen_compute_eflags_o(DisasContext *s, TCGv reg)
1050  {
1051      gen_compute_eflags(s);
1052      tcg_gen_shri_tl(reg, cpu_cc_src, 11);
1053      tcg_gen_andi_tl(reg, reg, 1);
1054  }
1055  
1056  /* compute eflags.Z to reg */
gen_compute_eflags_z(DisasContext * s,TCGv reg,bool inv)1057  static void gen_compute_eflags_z(DisasContext *s, TCGv reg, bool inv)
1058  {
1059      switch (s->cc_op) {
1060      case CC_OP_DYNAMIC:
1061          gen_compute_eflags(s);
1062          /* FALLTHRU */
1063      case CC_OP_EFLAGS:
1064          tcg_gen_shri_tl(reg, cpu_cc_src, 6);
1065          tcg_gen_andi_tl(reg, reg, 1);
1066          if (inv) {
1067              tcg_gen_xori_tl(reg, reg, 1);
1068          }
1069          break;
1070      default:
1071          {
1072              int size = (s->cc_op - CC_OP_ADDB) & 3;
1073              TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
1074              tcg_gen_setcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, reg, t0, 0);
1075          }
1076      }
1077  }
1078  
gen_setcc_slow(DisasContext * s,int jcc_op,TCGv reg,bool inv)1079  static void gen_setcc_slow(DisasContext *s, int jcc_op, TCGv reg, bool inv)
1080  {
1081      assert(!TCGV_EQUAL(reg, cpu_cc_src));
1082      switch(jcc_op) {
1083      case JCC_O:
1084          gen_compute_eflags_o(s, reg);
1085          break;
1086      case JCC_B:
1087          gen_compute_eflags_c(s, reg, inv);
1088          inv = false;
1089          break;
1090      case JCC_Z:
1091          gen_compute_eflags_z(s, reg, inv);
1092          inv = false;
1093          break;
1094      case JCC_BE:
1095          gen_compute_eflags(s);
1096          tcg_gen_andi_tl(reg, cpu_cc_src, CC_Z | CC_C);
1097          tcg_gen_setcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, reg, reg, 0);
1098          return;
1099      case JCC_S:
1100          gen_compute_eflags_s(s, reg, inv);
1101          inv = false;
1102          break;
1103      case JCC_P:
1104          gen_compute_eflags_p(s, reg);
1105          break;
1106      case JCC_L:
1107          gen_compute_eflags(s);
1108          tcg_gen_shri_tl(reg, cpu_cc_src, 11); /* CC_O */
1109          tcg_gen_shri_tl(cpu_tmp0, cpu_cc_src, 7); /* CC_S */
1110          tcg_gen_xor_tl(reg, reg, cpu_tmp0);
1111          tcg_gen_andi_tl(reg, reg, 1);
1112          break;
1113      default:
1114      case JCC_LE:
1115          gen_compute_eflags(s);
1116          tcg_gen_shri_tl(reg, cpu_cc_src, 11); /* CC_O */
1117          tcg_gen_shri_tl(cpu_tmp4, cpu_cc_src, 7); /* CC_S */
1118          tcg_gen_shri_tl(cpu_tmp0, cpu_cc_src, 6); /* CC_Z */
1119          tcg_gen_xor_tl(reg, reg, cpu_tmp4);
1120          tcg_gen_or_tl(reg, reg, cpu_tmp0);
1121          tcg_gen_andi_tl(reg, reg, 1);
1122          break;
1123      }
1124      if (inv) {
1125          tcg_gen_xori_tl(reg, reg, 1);
1126      }
1127  }
1128  
1129  /* return true if setcc_slow is not needed (WARNING: must be kept in
1130     sync with gen_jcc1) */
is_fast_jcc_case(DisasContext * s,int b)1131  static int is_fast_jcc_case(DisasContext *s, int b)
1132  {
1133      int jcc_op;
1134      jcc_op = (b >> 1) & 7;
1135      switch(s->cc_op) {
1136          /* we optimize the cmp/jcc case */
1137      case CC_OP_SUBB:
1138      case CC_OP_SUBW:
1139      case CC_OP_SUBL:
1140      case CC_OP_SUBQ:
1141          if (jcc_op == JCC_O || jcc_op == JCC_P)
1142              goto slow_jcc;
1143          break;
1144  
1145          /* some jumps are easy to compute */
1146      case CC_OP_ADDB:
1147      case CC_OP_ADDW:
1148      case CC_OP_ADDL:
1149      case CC_OP_ADDQ:
1150  
1151      case CC_OP_LOGICB:
1152      case CC_OP_LOGICW:
1153      case CC_OP_LOGICL:
1154      case CC_OP_LOGICQ:
1155  
1156      case CC_OP_INCB:
1157      case CC_OP_INCW:
1158      case CC_OP_INCL:
1159      case CC_OP_INCQ:
1160  
1161      case CC_OP_DECB:
1162      case CC_OP_DECW:
1163      case CC_OP_DECL:
1164      case CC_OP_DECQ:
1165  
1166      case CC_OP_SHLB:
1167      case CC_OP_SHLW:
1168      case CC_OP_SHLL:
1169      case CC_OP_SHLQ:
1170          if (jcc_op != JCC_Z && jcc_op != JCC_S)
1171              goto slow_jcc;
1172          break;
1173      default:
1174      slow_jcc:
1175          return 0;
1176      }
1177      return 1;
1178  }
1179  
1180  /* generate a conditional jump to label 'l1' according to jump opcode
1181     value 'b'. In the fast case, T0 is guaranted not to be used. */
gen_jcc1(DisasContext * s,int b,int l1)1182  static inline void gen_jcc1(DisasContext *s, int b, int l1)
1183  {
1184      int inv, jcc_op, size, cond;
1185      TCGv t0;
1186  
1187      inv = b & 1;
1188      jcc_op = (b >> 1) & 7;
1189  
1190      switch(s->cc_op) {
1191          /* we optimize the cmp/jcc case */
1192      case CC_OP_SUBB:
1193      case CC_OP_SUBW:
1194      case CC_OP_SUBL:
1195      case CC_OP_SUBQ:
1196  
1197          size = s->cc_op - CC_OP_SUBB;
1198          switch(jcc_op) {
1199          case JCC_Z:
1200          fast_jcc_z:
1201              t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, false);
1202              tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1);
1203              break;
1204          case JCC_S:
1205          fast_jcc_s:
1206              t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, true);
1207              tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, t0, 0, l1);
1208              break;
1209  
1210          case JCC_B:
1211              cond = inv ? TCG_COND_GEU : TCG_COND_LTU;
1212              goto fast_jcc_b;
1213          case JCC_BE:
1214              cond = inv ? TCG_COND_GTU : TCG_COND_LEU;
1215          fast_jcc_b:
1216              tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
1217              gen_extu(size, cpu_tmp4);
1218              t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
1219              tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
1220              break;
1221  
1222          case JCC_L:
1223              cond = inv ? TCG_COND_GE : TCG_COND_LT;
1224              goto fast_jcc_l;
1225          case JCC_LE:
1226              cond = inv ? TCG_COND_GT : TCG_COND_LE;
1227          fast_jcc_l:
1228              tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
1229              gen_exts(size, cpu_tmp4);
1230              t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
1231              tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
1232              break;
1233  
1234          default:
1235              goto slow_jcc;
1236          }
1237          break;
1238  
1239          /* some jumps are easy to compute */
1240      case CC_OP_ADDB:
1241      case CC_OP_ADDW:
1242      case CC_OP_ADDL:
1243      case CC_OP_ADDQ:
1244  
1245      case CC_OP_ADCB:
1246      case CC_OP_ADCW:
1247      case CC_OP_ADCL:
1248      case CC_OP_ADCQ:
1249  
1250      case CC_OP_SBBB:
1251      case CC_OP_SBBW:
1252      case CC_OP_SBBL:
1253      case CC_OP_SBBQ:
1254  
1255      case CC_OP_LOGICB:
1256      case CC_OP_LOGICW:
1257      case CC_OP_LOGICL:
1258      case CC_OP_LOGICQ:
1259  
1260      case CC_OP_INCB:
1261      case CC_OP_INCW:
1262      case CC_OP_INCL:
1263      case CC_OP_INCQ:
1264  
1265      case CC_OP_DECB:
1266      case CC_OP_DECW:
1267      case CC_OP_DECL:
1268      case CC_OP_DECQ:
1269  
1270      case CC_OP_SHLB:
1271      case CC_OP_SHLW:
1272      case CC_OP_SHLL:
1273      case CC_OP_SHLQ:
1274  
1275      case CC_OP_SARB:
1276      case CC_OP_SARW:
1277      case CC_OP_SARL:
1278      case CC_OP_SARQ:
1279          switch(jcc_op) {
1280          case JCC_Z:
1281              size = (s->cc_op - CC_OP_ADDB) & 3;
1282              goto fast_jcc_z;
1283          case JCC_S:
1284              size = (s->cc_op - CC_OP_ADDB) & 3;
1285              goto fast_jcc_s;
1286          default:
1287              goto slow_jcc;
1288          }
1289          break;
1290      default:
1291      slow_jcc:
1292          gen_setcc_slow(s, jcc_op, cpu_T[0], false);
1293          tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE,
1294                             cpu_T[0], 0, l1);
1295          break;
1296      }
1297  }
1298  
1299  /* XXX: does not work with gdbstub "ice" single step - not a
1300     serious problem */
gen_jz_ecx_string(DisasContext * s,target_ulong next_eip)1301  static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1302  {
1303      int l1, l2;
1304  
1305      l1 = gen_new_label();
1306      l2 = gen_new_label();
1307      gen_op_jnz_ecx(s->aflag, l1);
1308      gen_set_label(l2);
1309      gen_jmp_tb(s, next_eip, 1);
1310      gen_set_label(l1);
1311      return l2;
1312  }
1313  
gen_stos(DisasContext * s,int ot)1314  static inline void gen_stos(DisasContext *s, int ot)
1315  {
1316      gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1317      gen_string_movl_A0_EDI(s);
1318      gen_op_st_T0_A0(ot + s->mem_index);
1319      gen_op_movl_T0_Dshift(ot);
1320      gen_op_add_reg_T0(s->aflag, R_EDI);
1321  }
1322  
gen_lods(DisasContext * s,int ot)1323  static inline void gen_lods(DisasContext *s, int ot)
1324  {
1325      gen_string_movl_A0_ESI(s);
1326      gen_op_ld_T0_A0(ot + s->mem_index);
1327      gen_op_mov_reg_T0(ot, R_EAX);
1328      gen_op_movl_T0_Dshift(ot);
1329      gen_op_add_reg_T0(s->aflag, R_ESI);
1330  }
1331  
gen_scas(DisasContext * s,int ot)1332  static inline void gen_scas(DisasContext *s, int ot)
1333  {
1334      gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1335      gen_string_movl_A0_EDI(s);
1336      gen_op_ld_T1_A0(ot + s->mem_index);
1337      gen_op_cmpl_T0_T1_cc();
1338      gen_op_movl_T0_Dshift(ot);
1339      gen_op_add_reg_T0(s->aflag, R_EDI);
1340      set_cc_op(s, CC_OP_SUBB + ot);
1341  }
1342  
gen_cmps(DisasContext * s,int ot)1343  static inline void gen_cmps(DisasContext *s, int ot)
1344  {
1345      gen_string_movl_A0_ESI(s);
1346      gen_op_ld_T0_A0(ot + s->mem_index);
1347      gen_string_movl_A0_EDI(s);
1348      gen_op_ld_T1_A0(ot + s->mem_index);
1349      gen_op_cmpl_T0_T1_cc();
1350      gen_op_movl_T0_Dshift(ot);
1351      gen_op_add_reg_T0(s->aflag, R_ESI);
1352      gen_op_add_reg_T0(s->aflag, R_EDI);
1353      set_cc_op(s, CC_OP_SUBB + ot);
1354  }
1355  
gen_ins(DisasContext * s,int ot)1356  static inline void gen_ins(DisasContext *s, int ot)
1357  {
1358      if (use_icount)
1359          gen_io_start();
1360      gen_string_movl_A0_EDI(s);
1361      /* Note: we must do this dummy write first to be restartable in
1362         case of page fault. */
1363      gen_op_movl_T0_0();
1364      gen_op_st_T0_A0(ot + s->mem_index);
1365      gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1366      tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1367      tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1368      gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
1369      gen_op_st_T0_A0(ot + s->mem_index);
1370      gen_op_movl_T0_Dshift(ot);
1371      gen_op_add_reg_T0(s->aflag, R_EDI);
1372      if (use_icount)
1373          gen_io_end();
1374  }
1375  
gen_outs(DisasContext * s,int ot)1376  static inline void gen_outs(DisasContext *s, int ot)
1377  {
1378      if (use_icount)
1379          gen_io_start();
1380      gen_string_movl_A0_ESI(s);
1381      gen_op_ld_T0_A0(ot + s->mem_index);
1382  
1383      gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1384      tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1385      tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1386      tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1387      gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1388  
1389      gen_op_movl_T0_Dshift(ot);
1390      gen_op_add_reg_T0(s->aflag, R_ESI);
1391      if (use_icount)
1392          gen_io_end();
1393  }
1394  
1395  /* same method as Valgrind : we generate jumps to current or next
1396     instruction */
1397  #define GEN_REPZ(op)                                                          \
1398  static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1399                                   target_ulong cur_eip, target_ulong next_eip) \
1400  {                                                                             \
1401      int l2;\
1402      gen_update_cc_op(s);                                                      \
1403      l2 = gen_jz_ecx_string(s, next_eip);                                      \
1404      gen_ ## op(s, ot);                                                        \
1405      gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1406      /* a loop would cause two single step exceptions if ECX = 1               \
1407         before rep string_insn */                                              \
1408      if (!s->jmp_opt)                                                          \
1409          gen_op_jz_ecx(s->aflag, l2);                                          \
1410      gen_jmp(s, cur_eip);                                                      \
1411  }
1412  
1413  #define GEN_REPZ2(op)                                                         \
1414  static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1415                                     target_ulong cur_eip,                      \
1416                                     target_ulong next_eip,                     \
1417                                     int nz)                                    \
1418  {                                                                             \
1419      int l2;\
1420      gen_update_cc_op(s);                                                      \
1421      l2 = gen_jz_ecx_string(s, next_eip);                                      \
1422      gen_ ## op(s, ot);                                                        \
1423      gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1424      gen_update_cc_op(s);                                                      \
1425      gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);                                 \
1426      if (!s->jmp_opt)                                                          \
1427          gen_op_jz_ecx(s->aflag, l2);                                          \
1428      gen_jmp(s, cur_eip);                                                      \
1429  }
1430  
1431  GEN_REPZ(movs)
GEN_REPZ(stos)1432  GEN_REPZ(stos)
1433  GEN_REPZ(lods)
1434  GEN_REPZ(ins)
1435  GEN_REPZ(outs)
1436  GEN_REPZ2(scas)
1437  GEN_REPZ2(cmps)
1438  
1439  static void gen_helper_fp_arith_ST0_FT0(int op)
1440  {
1441      switch (op) {
1442      case 0:
1443          gen_helper_fadd_ST0_FT0(cpu_env);
1444          break;
1445      case 1:
1446          gen_helper_fmul_ST0_FT0(cpu_env);
1447          break;
1448      case 2:
1449          gen_helper_fcom_ST0_FT0(cpu_env);
1450          break;
1451      case 3:
1452          gen_helper_fcom_ST0_FT0(cpu_env);
1453          break;
1454      case 4:
1455          gen_helper_fsub_ST0_FT0(cpu_env);
1456          break;
1457      case 5:
1458          gen_helper_fsubr_ST0_FT0(cpu_env);
1459          break;
1460      case 6:
1461          gen_helper_fdiv_ST0_FT0(cpu_env);
1462          break;
1463      case 7:
1464          gen_helper_fdivr_ST0_FT0(cpu_env);
1465          break;
1466      }
1467  }
1468  
1469  /* NOTE the exception in "r" op ordering */
gen_helper_fp_arith_STN_ST0(int op,int opreg)1470  static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1471  {
1472      TCGv_i32 tmp = tcg_const_i32(opreg);
1473      switch (op) {
1474      case 0:
1475          gen_helper_fadd_STN_ST0(cpu_env, tmp);
1476          break;
1477      case 1:
1478          gen_helper_fmul_STN_ST0(cpu_env, tmp);
1479          break;
1480      case 4:
1481          gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1482          break;
1483      case 5:
1484          gen_helper_fsub_STN_ST0(cpu_env, tmp);
1485          break;
1486      case 6:
1487          gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1488          break;
1489      case 7:
1490          gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1491          break;
1492      }
1493  }
1494  
1495  /* if d == OR_TMP0, it means memory operand (address in A0) */
gen_op(DisasContext * s1,int op,int ot,int d)1496  static void gen_op(DisasContext *s1, int op, int ot, int d)
1497  {
1498      if (d != OR_TMP0) {
1499          gen_op_mov_TN_reg(ot, 0, d);
1500      } else {
1501          gen_op_ld_T0_A0(ot + s1->mem_index);
1502      }
1503      switch(op) {
1504      case OP_ADCL:
1505          gen_compute_eflags_c(s1, cpu_tmp4, false);
1506          tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1507          tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1508          if (d != OR_TMP0)
1509              gen_op_mov_reg_T0(ot, d);
1510          else
1511              gen_op_st_T0_A0(ot + s1->mem_index);
1512          tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1513          tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1514          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
1515          tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
1516          tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_ADDB + ot);
1517          set_cc_op(s1, CC_OP_DYNAMIC);
1518          break;
1519      case OP_SBBL:
1520          gen_compute_eflags_c(s1, cpu_tmp4, false);
1521          tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1522          tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1523          if (d != OR_TMP0)
1524              gen_op_mov_reg_T0(ot, d);
1525          else
1526              gen_op_st_T0_A0(ot + s1->mem_index);
1527          tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1528          tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1529          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
1530          tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
1531          tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_SUBB + ot);
1532          set_cc_op(s1, CC_OP_DYNAMIC);
1533          break;
1534      case OP_ADDL:
1535          gen_op_addl_T0_T1();
1536          if (d != OR_TMP0)
1537              gen_op_mov_reg_T0(ot, d);
1538          else
1539              gen_op_st_T0_A0(ot + s1->mem_index);
1540          gen_op_update2_cc();
1541          set_cc_op(s1, CC_OP_ADDB + ot);
1542          break;
1543      case OP_SUBL:
1544          tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1545          if (d != OR_TMP0)
1546              gen_op_mov_reg_T0(ot, d);
1547          else
1548              gen_op_st_T0_A0(ot + s1->mem_index);
1549          gen_op_update2_cc();
1550          set_cc_op(s1, CC_OP_SUBB + ot);
1551          break;
1552      default:
1553      case OP_ANDL:
1554          tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1555          if (d != OR_TMP0)
1556              gen_op_mov_reg_T0(ot, d);
1557          else
1558              gen_op_st_T0_A0(ot + s1->mem_index);
1559          gen_op_update1_cc();
1560          set_cc_op(s1, CC_OP_LOGICB + ot);
1561          break;
1562      case OP_ORL:
1563          tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1564          if (d != OR_TMP0)
1565              gen_op_mov_reg_T0(ot, d);
1566          else
1567              gen_op_st_T0_A0(ot + s1->mem_index);
1568          gen_op_update1_cc();
1569          set_cc_op(s1, CC_OP_LOGICB + ot);
1570          break;
1571      case OP_XORL:
1572          tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1573          if (d != OR_TMP0)
1574              gen_op_mov_reg_T0(ot, d);
1575          else
1576              gen_op_st_T0_A0(ot + s1->mem_index);
1577          gen_op_update1_cc();
1578          set_cc_op(s1, CC_OP_LOGICB + ot);
1579          break;
1580      case OP_CMPL:
1581          gen_op_cmpl_T0_T1_cc();
1582          set_cc_op(s1, CC_OP_SUBB + ot);
1583          break;
1584      }
1585  }
1586  
1587  /* if d == OR_TMP0, it means memory operand (address in A0) */
gen_inc(DisasContext * s1,int ot,int d,int c)1588  static void gen_inc(DisasContext *s1, int ot, int d, int c)
1589  {
1590      if (d != OR_TMP0)
1591          gen_op_mov_TN_reg(ot, 0, d);
1592      else
1593          gen_op_ld_T0_A0(ot + s1->mem_index);
1594      gen_compute_eflags_c(s1, cpu_cc_src, false);
1595      if (c > 0) {
1596          tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
1597          set_cc_op(s1, CC_OP_INCB + ot);
1598      } else {
1599          tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
1600          set_cc_op(s1, CC_OP_DECB + ot);
1601      }
1602      if (d != OR_TMP0)
1603          gen_op_mov_reg_T0(ot, d);
1604      else
1605          gen_op_st_T0_A0(ot + s1->mem_index);
1606      tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1607  }
1608  
gen_shift_rm_T1(DisasContext * s,int ot,int op1,int is_right,int is_arith)1609  static void gen_shift_rm_T1(DisasContext *s, int ot, int op1,
1610                              int is_right, int is_arith)
1611  {
1612      target_ulong mask;
1613      int shift_label;
1614      TCGv t0, t1;
1615  
1616      if (ot == OT_QUAD)
1617          mask = 0x3f;
1618      else
1619          mask = 0x1f;
1620  
1621      /* load */
1622      if (op1 == OR_TMP0) {
1623          gen_op_ld_T0_A0(ot + s->mem_index);
1624      } else {
1625          gen_op_mov_TN_reg(ot, 0, op1);
1626      }
1627  
1628      tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1629  
1630      tcg_gen_addi_tl(cpu_tmp5, cpu_T[1], -1);
1631  
1632      if (is_right) {
1633          if (is_arith) {
1634              gen_exts(ot, cpu_T[0]);
1635              tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1636              tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1637          } else {
1638              gen_extu(ot, cpu_T[0]);
1639              tcg_gen_shr_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1640              tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1641          }
1642      } else {
1643          tcg_gen_shl_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1644          tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1645      }
1646  
1647      /* store */
1648      if (op1 == OR_TMP0) {
1649          gen_op_st_T0_A0(ot + s->mem_index);
1650      } else {
1651          gen_op_mov_reg_T0(ot, op1);
1652      }
1653  
1654      /* update eflags */
1655      gen_update_cc_op(s);
1656  
1657      /* XXX: inefficient */
1658      t0 = tcg_temp_local_new();
1659      t1 = tcg_temp_local_new();
1660  
1661      tcg_gen_mov_tl(t0, cpu_T[0]);
1662      tcg_gen_mov_tl(t1, cpu_T3);
1663  
1664      shift_label = gen_new_label();
1665      tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, shift_label);
1666  
1667      tcg_gen_mov_tl(cpu_cc_src, t1);
1668      tcg_gen_mov_tl(cpu_cc_dst, t0);
1669      if (is_right)
1670          tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1671      else
1672          tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1673  
1674      gen_set_label(shift_label);
1675      set_cc_op(s, CC_OP_DYNAMIC); /* cannot predict flags after */
1676  
1677      tcg_temp_free(t0);
1678      tcg_temp_free(t1);
1679  }
1680  
gen_shift_rm_im(DisasContext * s,int ot,int op1,int op2,int is_right,int is_arith)1681  static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2,
1682                              int is_right, int is_arith)
1683  {
1684      int mask = (ot == OT_QUAD ? 0x3f : 0x1f);
1685  
1686      /* load */
1687      if (op1 == OR_TMP0)
1688          gen_op_ld_T0_A0(ot + s->mem_index);
1689      else
1690          gen_op_mov_TN_reg(ot, 0, op1);
1691  
1692      op2 &= mask;
1693      if (op2 != 0) {
1694          if (is_right) {
1695              if (is_arith) {
1696                  gen_exts(ot, cpu_T[0]);
1697                  tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1698                  tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
1699              } else {
1700                  gen_extu(ot, cpu_T[0]);
1701                  tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1702                  tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
1703              }
1704          } else {
1705              tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1706              tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
1707          }
1708      }
1709  
1710      /* store */
1711      if (op1 == OR_TMP0)
1712          gen_op_st_T0_A0(ot + s->mem_index);
1713      else
1714          gen_op_mov_reg_T0(ot, op1);
1715  
1716      /* update eflags if non zero shift */
1717      if (op2 != 0) {
1718          tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1719          tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1720          if (is_right)
1721              set_cc_op(s, CC_OP_SARB + ot);
1722          else
1723              set_cc_op(s, CC_OP_SHLB + ot);
1724      }
1725  }
1726  
tcg_gen_lshift(TCGv ret,TCGv arg1,target_long arg2)1727  static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
1728  {
1729      if (arg2 >= 0)
1730          tcg_gen_shli_tl(ret, arg1, arg2);
1731      else
1732          tcg_gen_shri_tl(ret, arg1, -arg2);
1733  }
1734  
gen_rot_rm_T1(DisasContext * s,int ot,int op1,int is_right)1735  static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, int is_right)
1736  {
1737      target_ulong mask;
1738      int label1, label2, data_bits;
1739      TCGv t0, t1, t2, a0;
1740  
1741      /* XXX: inefficient, but we must use local temps */
1742      t0 = tcg_temp_local_new();
1743      t1 = tcg_temp_local_new();
1744      t2 = tcg_temp_local_new();
1745      a0 = tcg_temp_local_new();
1746  
1747      if (ot == OT_QUAD)
1748          mask = 0x3f;
1749      else
1750          mask = 0x1f;
1751  
1752      /* load */
1753      if (op1 == OR_TMP0) {
1754          tcg_gen_mov_tl(a0, cpu_A0);
1755          gen_op_ld_v(ot + s->mem_index, t0, a0);
1756      } else {
1757          gen_op_mov_v_reg(ot, t0, op1);
1758      }
1759  
1760      tcg_gen_mov_tl(t1, cpu_T[1]);
1761  
1762      tcg_gen_andi_tl(t1, t1, mask);
1763  
1764      /* Must test zero case to avoid using undefined behaviour in TCG
1765         shifts. */
1766      label1 = gen_new_label();
1767      tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1);
1768  
1769      if (ot <= OT_WORD)
1770          tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1);
1771      else
1772          tcg_gen_mov_tl(cpu_tmp0, t1);
1773  
1774      gen_extu(ot, t0);
1775      tcg_gen_mov_tl(t2, t0);
1776  
1777      data_bits = 8 << ot;
1778      /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1779         fix TCG definition) */
1780      if (is_right) {
1781          tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0);
1782          tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(data_bits), cpu_tmp0);
1783          tcg_gen_shl_tl(t0, t0, cpu_tmp0);
1784      } else {
1785          tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0);
1786          tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(data_bits), cpu_tmp0);
1787          tcg_gen_shr_tl(t0, t0, cpu_tmp0);
1788      }
1789      tcg_gen_or_tl(t0, t0, cpu_tmp4);
1790  
1791      gen_set_label(label1);
1792      /* store */
1793      if (op1 == OR_TMP0) {
1794          gen_op_st_v(ot + s->mem_index, t0, a0);
1795      } else {
1796          gen_op_mov_reg_v(ot, op1, t0);
1797      }
1798  
1799      /* update eflags.  It is needed anyway most of the time, do it always.  */
1800      gen_compute_eflags(s);
1801      assert(s->cc_op == CC_OP_EFLAGS);
1802  
1803      label2 = gen_new_label();
1804      tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
1805  
1806      tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1807      tcg_gen_xor_tl(cpu_tmp0, t2, t0);
1808      tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1809      tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1810      tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1811      if (is_right) {
1812          tcg_gen_shri_tl(t0, t0, data_bits - 1);
1813      }
1814      tcg_gen_andi_tl(t0, t0, CC_C);
1815      tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1816  
1817      gen_set_label(label2);
1818  
1819      tcg_temp_free(t0);
1820      tcg_temp_free(t1);
1821      tcg_temp_free(t2);
1822      tcg_temp_free(a0);
1823  }
1824  
gen_rot_rm_im(DisasContext * s,int ot,int op1,int op2,int is_right)1825  static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
1826                            int is_right)
1827  {
1828      int mask;
1829      int data_bits;
1830      TCGv t0, t1, a0;
1831  
1832      /* XXX: inefficient, but we must use local temps */
1833      t0 = tcg_temp_local_new();
1834      t1 = tcg_temp_local_new();
1835      a0 = tcg_temp_local_new();
1836  
1837      if (ot == OT_QUAD)
1838          mask = 0x3f;
1839      else
1840          mask = 0x1f;
1841  
1842      /* load */
1843      if (op1 == OR_TMP0) {
1844          tcg_gen_mov_tl(a0, cpu_A0);
1845          gen_op_ld_v(ot + s->mem_index, t0, a0);
1846      } else {
1847          gen_op_mov_v_reg(ot, t0, op1);
1848      }
1849  
1850      gen_extu(ot, t0);
1851      tcg_gen_mov_tl(t1, t0);
1852  
1853      op2 &= mask;
1854      data_bits = 8 << ot;
1855      if (op2 != 0) {
1856          int shift = op2 & ((1 << (3 + ot)) - 1);
1857          if (is_right) {
1858              tcg_gen_shri_tl(cpu_tmp4, t0, shift);
1859              tcg_gen_shli_tl(t0, t0, data_bits - shift);
1860          }
1861          else {
1862              tcg_gen_shli_tl(cpu_tmp4, t0, shift);
1863              tcg_gen_shri_tl(t0, t0, data_bits - shift);
1864          }
1865          tcg_gen_or_tl(t0, t0, cpu_tmp4);
1866      }
1867  
1868      /* store */
1869      if (op1 == OR_TMP0) {
1870          gen_op_st_v(ot + s->mem_index, t0, a0);
1871      } else {
1872          gen_op_mov_reg_v(ot, op1, t0);
1873      }
1874  
1875      if (op2 != 0) {
1876          /* update eflags */
1877          gen_compute_eflags(s);
1878          assert(s->cc_op == CC_OP_EFLAGS);
1879  
1880          tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1881          tcg_gen_xor_tl(cpu_tmp0, t1, t0);
1882          tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1883          tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1884          tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1885          if (is_right) {
1886              tcg_gen_shri_tl(t0, t0, data_bits - 1);
1887          }
1888          tcg_gen_andi_tl(t0, t0, CC_C);
1889          tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1890  
1891          tcg_gen_discard_tl(cpu_cc_dst);
1892          tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1893      }
1894  
1895      tcg_temp_free(t0);
1896      tcg_temp_free(t1);
1897      tcg_temp_free(a0);
1898  }
1899  
1900  /* XXX: add faster immediate = 1 case */
gen_rotc_rm_T1(DisasContext * s,int ot,int op1,int is_right)1901  static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1,
1902                             int is_right)
1903  {
1904      gen_compute_eflags(s);
1905      assert(s->cc_op == CC_OP_EFLAGS);
1906      tcg_gen_discard_tl(cpu_cc_dst);
1907      set_cc_op(s, CC_OP_EFLAGS);
1908  
1909      /* load */
1910      if (op1 == OR_TMP0)
1911          gen_op_ld_T0_A0(ot + s->mem_index);
1912      else
1913          gen_op_mov_TN_reg(ot, 0, op1);
1914  
1915      if (is_right) {
1916          switch (ot) {
1917          case OT_BYTE:
1918              gen_helper_rcrb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1919              break;
1920          case OT_WORD:
1921              gen_helper_rcrw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1922              break;
1923          case OT_LONG:
1924              gen_helper_rcrl(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1925              break;
1926  #ifdef TARGET_X86_64
1927          case OT_QUAD:
1928              gen_helper_rcrq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1929              break;
1930  #endif
1931          }
1932      } else {
1933          switch (ot) {
1934          case OT_BYTE:
1935              gen_helper_rclb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1936              break;
1937          case OT_WORD:
1938              gen_helper_rclw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1939              break;
1940          case OT_LONG:
1941              gen_helper_rcll(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1942              break;
1943  #ifdef TARGET_X86_64
1944          case OT_QUAD:
1945              gen_helper_rclq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1946              break;
1947  #endif
1948          }
1949      }
1950      /* store */
1951      if (op1 == OR_TMP0)
1952          gen_op_st_T0_A0(ot + s->mem_index);
1953      else
1954          gen_op_mov_reg_T0(ot, op1);
1955  }
1956  
1957  /* XXX: add faster immediate case */
gen_shiftd_rm_T1_T3(DisasContext * s,int ot,int op1,int is_right)1958  static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1,
1959                                  int is_right)
1960  {
1961      int label1, label2, data_bits;
1962      target_ulong mask;
1963      TCGv t0, t1, t2, a0;
1964  
1965      t0 = tcg_temp_local_new();
1966      t1 = tcg_temp_local_new();
1967      t2 = tcg_temp_local_new();
1968      a0 = tcg_temp_local_new();
1969  
1970      if (ot == OT_QUAD)
1971          mask = 0x3f;
1972      else
1973          mask = 0x1f;
1974  
1975      /* load */
1976      if (op1 == OR_TMP0) {
1977          tcg_gen_mov_tl(a0, cpu_A0);
1978          gen_op_ld_v(ot + s->mem_index, t0, a0);
1979      } else {
1980          gen_op_mov_v_reg(ot, t0, op1);
1981      }
1982  
1983      tcg_gen_andi_tl(cpu_T3, cpu_T3, mask);
1984  
1985      tcg_gen_mov_tl(t1, cpu_T[1]);
1986      tcg_gen_mov_tl(t2, cpu_T3);
1987  
1988      /* Must test zero case to avoid using undefined behaviour in TCG
1989         shifts. */
1990      label1 = gen_new_label();
1991      tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
1992  
1993      tcg_gen_addi_tl(cpu_tmp5, t2, -1);
1994      if (ot == OT_WORD) {
1995          /* Note: we implement the Intel behaviour for shift count > 16 */
1996          if (is_right) {
1997              tcg_gen_andi_tl(t0, t0, 0xffff);
1998              tcg_gen_shli_tl(cpu_tmp0, t1, 16);
1999              tcg_gen_or_tl(t0, t0, cpu_tmp0);
2000              tcg_gen_ext32u_tl(t0, t0);
2001  
2002              tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
2003  
2004              /* only needed if count > 16, but a test would complicate */
2005              tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2);
2006              tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
2007  
2008              tcg_gen_shr_tl(t0, t0, t2);
2009  
2010              tcg_gen_or_tl(t0, t0, cpu_tmp0);
2011          } else {
2012              /* XXX: not optimal */
2013              tcg_gen_andi_tl(t0, t0, 0xffff);
2014              tcg_gen_shli_tl(t1, t1, 16);
2015              tcg_gen_or_tl(t1, t1, t0);
2016              tcg_gen_ext32u_tl(t1, t1);
2017  
2018              tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
2019              tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(32), cpu_tmp5);
2020              tcg_gen_shr_tl(cpu_tmp6, t1, cpu_tmp0);
2021              tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp6);
2022  
2023              tcg_gen_shl_tl(t0, t0, t2);
2024              tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2);
2025              tcg_gen_shr_tl(t1, t1, cpu_tmp5);
2026              tcg_gen_or_tl(t0, t0, t1);
2027          }
2028      } else {
2029          data_bits = 8 << ot;
2030          if (is_right) {
2031              if (ot == OT_LONG)
2032                  tcg_gen_ext32u_tl(t0, t0);
2033  
2034              tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
2035  
2036              tcg_gen_shr_tl(t0, t0, t2);
2037              tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2);
2038              tcg_gen_shl_tl(t1, t1, cpu_tmp5);
2039              tcg_gen_or_tl(t0, t0, t1);
2040  
2041          } else {
2042              if (ot == OT_LONG)
2043                  tcg_gen_ext32u_tl(t1, t1);
2044  
2045              tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
2046  
2047              tcg_gen_shl_tl(t0, t0, t2);
2048              tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2);
2049              tcg_gen_shr_tl(t1, t1, cpu_tmp5);
2050              tcg_gen_or_tl(t0, t0, t1);
2051          }
2052      }
2053      tcg_gen_mov_tl(t1, cpu_tmp4);
2054  
2055      gen_set_label(label1);
2056      /* store */
2057      if (op1 == OR_TMP0) {
2058          gen_op_st_v(ot + s->mem_index, t0, a0);
2059      } else {
2060          gen_op_mov_reg_v(ot, op1, t0);
2061      }
2062  
2063      /* update eflags */
2064      gen_update_cc_op(s);
2065  
2066      label2 = gen_new_label();
2067      tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
2068  
2069      tcg_gen_mov_tl(cpu_cc_src, t1);
2070      tcg_gen_mov_tl(cpu_cc_dst, t0);
2071      if (is_right) {
2072          tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
2073      } else {
2074          tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
2075      }
2076      gen_set_label(label2);
2077      set_cc_op(s, CC_OP_DYNAMIC); /* cannot predict flags after */
2078  
2079      tcg_temp_free(t0);
2080      tcg_temp_free(t1);
2081      tcg_temp_free(t2);
2082      tcg_temp_free(a0);
2083  }
2084  
gen_shift(DisasContext * s1,int op,int ot,int d,int s)2085  static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
2086  {
2087      if (s != OR_TMP1)
2088          gen_op_mov_TN_reg(ot, 1, s);
2089      switch(op) {
2090      case OP_ROL:
2091          gen_rot_rm_T1(s1, ot, d, 0);
2092          break;
2093      case OP_ROR:
2094          gen_rot_rm_T1(s1, ot, d, 1);
2095          break;
2096      case OP_SHL:
2097      case OP_SHL1:
2098          gen_shift_rm_T1(s1, ot, d, 0, 0);
2099          break;
2100      case OP_SHR:
2101          gen_shift_rm_T1(s1, ot, d, 1, 0);
2102          break;
2103      case OP_SAR:
2104          gen_shift_rm_T1(s1, ot, d, 1, 1);
2105          break;
2106      case OP_RCL:
2107          gen_rotc_rm_T1(s1, ot, d, 0);
2108          break;
2109      case OP_RCR:
2110          gen_rotc_rm_T1(s1, ot, d, 1);
2111          break;
2112      }
2113  }
2114  
gen_shifti(DisasContext * s1,int op,int ot,int d,int c)2115  static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
2116  {
2117      switch(op) {
2118      case OP_ROL:
2119          gen_rot_rm_im(s1, ot, d, c, 0);
2120          break;
2121      case OP_ROR:
2122          gen_rot_rm_im(s1, ot, d, c, 1);
2123          break;
2124      case OP_SHL:
2125      case OP_SHL1:
2126          gen_shift_rm_im(s1, ot, d, c, 0, 0);
2127          break;
2128      case OP_SHR:
2129          gen_shift_rm_im(s1, ot, d, c, 1, 0);
2130          break;
2131      case OP_SAR:
2132          gen_shift_rm_im(s1, ot, d, c, 1, 1);
2133          break;
2134      default:
2135          /* currently not optimized */
2136          gen_op_movl_T1_im(c);
2137          gen_shift(s1, op, ot, d, OR_TMP1);
2138          break;
2139      }
2140  }
2141  
gen_lea_modrm(CPUX86State * env,DisasContext * s,int modrm,int * reg_ptr,int * offset_ptr)2142  static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm,
2143                            int *reg_ptr, int *offset_ptr)
2144  {
2145      target_long disp;
2146      int havesib;
2147      int base;
2148      int index;
2149      int scale;
2150      int opreg;
2151      int mod, rm, code, override, must_add_seg;
2152  
2153      override = s->override;
2154      must_add_seg = s->addseg;
2155      if (override >= 0)
2156          must_add_seg = 1;
2157      mod = (modrm >> 6) & 3;
2158      rm = modrm & 7;
2159  
2160      if (s->aflag) {
2161  
2162          havesib = 0;
2163          base = rm;
2164          index = 0;
2165          scale = 0;
2166  
2167          if (base == 4) {
2168              havesib = 1;
2169              code = cpu_ldub_code(env, s->pc++);
2170              scale = (code >> 6) & 3;
2171              index = ((code >> 3) & 7) | REX_X(s);
2172              base = (code & 7);
2173          }
2174          base |= REX_B(s);
2175  
2176          switch (mod) {
2177          case 0:
2178              if ((base & 7) == 5) {
2179                  base = -1;
2180                  disp = (int32_t)cpu_ldl_code(env, s->pc);
2181                  s->pc += 4;
2182                  if (CODE64(s) && !havesib) {
2183                      disp += s->pc + s->rip_offset;
2184                  }
2185              } else {
2186                  disp = 0;
2187              }
2188              break;
2189          case 1:
2190              disp = (int8_t)cpu_ldub_code(env, s->pc++);
2191              break;
2192          default:
2193          case 2:
2194              disp = cpu_ldl_code(env, s->pc);
2195              s->pc += 4;
2196              break;
2197          }
2198  
2199          if (base >= 0) {
2200              /* for correct popl handling with esp */
2201              if (base == 4 && s->popl_esp_hack)
2202                  disp += s->popl_esp_hack;
2203  #ifdef TARGET_X86_64
2204              if (s->aflag == 2) {
2205                  gen_op_movq_A0_reg(base);
2206                  if (disp != 0) {
2207                      gen_op_addq_A0_im(disp);
2208                  }
2209              } else
2210  #endif
2211              {
2212                  gen_op_movl_A0_reg(base);
2213                  if (disp != 0)
2214                      gen_op_addl_A0_im(disp);
2215              }
2216          } else {
2217  #ifdef TARGET_X86_64
2218              if (s->aflag == 2) {
2219                  gen_op_movq_A0_im(disp);
2220              } else
2221  #endif
2222              {
2223                  gen_op_movl_A0_im(disp);
2224              }
2225          }
2226          /* XXX: index == 4 is always invalid */
2227          if (havesib && (index != 4 || scale != 0)) {
2228  #ifdef TARGET_X86_64
2229              if (s->aflag == 2) {
2230                  gen_op_addq_A0_reg_sN(scale, index);
2231              } else
2232  #endif
2233              {
2234                  gen_op_addl_A0_reg_sN(scale, index);
2235              }
2236          }
2237          if (must_add_seg) {
2238              if (override < 0) {
2239                  if (base == R_EBP || base == R_ESP)
2240                      override = R_SS;
2241                  else
2242                      override = R_DS;
2243              }
2244  #ifdef TARGET_X86_64
2245              if (s->aflag == 2) {
2246                  gen_op_addq_A0_seg(override);
2247              } else
2248  #endif
2249              {
2250                  gen_op_addl_A0_seg(s, override);
2251              }
2252          }
2253      } else {
2254          switch (mod) {
2255          case 0:
2256              if (rm == 6) {
2257                  disp = cpu_lduw_code(env, s->pc);
2258                  s->pc += 2;
2259                  gen_op_movl_A0_im(disp);
2260                  rm = 0; /* avoid SS override */
2261                  goto no_rm;
2262              } else {
2263                  disp = 0;
2264              }
2265              break;
2266          case 1:
2267              disp = (int8_t)cpu_ldub_code(env, s->pc++);
2268              break;
2269          default:
2270          case 2:
2271              disp = cpu_lduw_code(env, s->pc);
2272              s->pc += 2;
2273              break;
2274          }
2275          switch(rm) {
2276          case 0:
2277              gen_op_movl_A0_reg(R_EBX);
2278              gen_op_addl_A0_reg_sN(0, R_ESI);
2279              break;
2280          case 1:
2281              gen_op_movl_A0_reg(R_EBX);
2282              gen_op_addl_A0_reg_sN(0, R_EDI);
2283              break;
2284          case 2:
2285              gen_op_movl_A0_reg(R_EBP);
2286              gen_op_addl_A0_reg_sN(0, R_ESI);
2287              break;
2288          case 3:
2289              gen_op_movl_A0_reg(R_EBP);
2290              gen_op_addl_A0_reg_sN(0, R_EDI);
2291              break;
2292          case 4:
2293              gen_op_movl_A0_reg(R_ESI);
2294              break;
2295          case 5:
2296              gen_op_movl_A0_reg(R_EDI);
2297              break;
2298          case 6:
2299              gen_op_movl_A0_reg(R_EBP);
2300              break;
2301          default:
2302          case 7:
2303              gen_op_movl_A0_reg(R_EBX);
2304              break;
2305          }
2306          if (disp != 0)
2307              gen_op_addl_A0_im(disp);
2308          gen_op_andl_A0_ffff();
2309      no_rm:
2310          if (must_add_seg) {
2311              if (override < 0) {
2312                  if (rm == 2 || rm == 3 || rm == 6)
2313                      override = R_SS;
2314                  else
2315                      override = R_DS;
2316              }
2317              gen_op_addl_A0_seg(s, override);
2318          }
2319      }
2320  
2321      opreg = OR_A0;
2322      disp = 0;
2323      *reg_ptr = opreg;
2324      *offset_ptr = disp;
2325  }
2326  
gen_nop_modrm(CPUX86State * env,DisasContext * s,int modrm)2327  static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2328  {
2329      int mod, rm, base, code;
2330  
2331      mod = (modrm >> 6) & 3;
2332      if (mod == 3)
2333          return;
2334      rm = modrm & 7;
2335  
2336      if (s->aflag) {
2337  
2338          base = rm;
2339  
2340          if (base == 4) {
2341              code = cpu_ldub_code(env, s->pc++);
2342              base = (code & 7);
2343          }
2344  
2345          switch (mod) {
2346          case 0:
2347              if (base == 5) {
2348                  s->pc += 4;
2349              }
2350              break;
2351          case 1:
2352              s->pc++;
2353              break;
2354          default:
2355          case 2:
2356              s->pc += 4;
2357              break;
2358          }
2359      } else {
2360          switch (mod) {
2361          case 0:
2362              if (rm == 6) {
2363                  s->pc += 2;
2364              }
2365              break;
2366          case 1:
2367              s->pc++;
2368              break;
2369          default:
2370          case 2:
2371              s->pc += 2;
2372              break;
2373          }
2374      }
2375  }
2376  
2377  /* used for LEA and MOV AX, mem */
gen_add_A0_ds_seg(DisasContext * s)2378  static void gen_add_A0_ds_seg(DisasContext *s)
2379  {
2380      int override, must_add_seg;
2381      must_add_seg = s->addseg;
2382      override = R_DS;
2383      if (s->override >= 0) {
2384          override = s->override;
2385          must_add_seg = 1;
2386      } else {
2387          override = R_DS;
2388      }
2389      if (must_add_seg) {
2390  #ifdef TARGET_X86_64
2391          if (CODE64(s)) {
2392              gen_op_addq_A0_seg(override);
2393          } else
2394  #endif
2395          {
2396              gen_op_addl_A0_seg(s, override);
2397          }
2398      }
2399  }
2400  
2401  /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2402     OR_TMP0 */
gen_ldst_modrm(CPUX86State * env,DisasContext * s,int modrm,int ot,int reg,int is_store)2403  static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2404                             int ot, int reg, int is_store)
2405  {
2406      int mod, rm, opreg, disp;
2407  
2408      mod = (modrm >> 6) & 3;
2409      rm = (modrm & 7) | REX_B(s);
2410      if (mod == 3) {
2411          if (is_store) {
2412              if (reg != OR_TMP0)
2413                  gen_op_mov_TN_reg(ot, 0, reg);
2414              gen_op_mov_reg_T0(ot, rm);
2415          } else {
2416              gen_op_mov_TN_reg(ot, 0, rm);
2417              if (reg != OR_TMP0)
2418                  gen_op_mov_reg_T0(ot, reg);
2419          }
2420      } else {
2421          gen_lea_modrm(env, s, modrm, &opreg, &disp);
2422          if (is_store) {
2423              if (reg != OR_TMP0)
2424                  gen_op_mov_TN_reg(ot, 0, reg);
2425              gen_op_st_T0_A0(ot + s->mem_index);
2426          } else {
2427              gen_op_ld_T0_A0(ot + s->mem_index);
2428              if (reg != OR_TMP0)
2429                  gen_op_mov_reg_T0(ot, reg);
2430          }
2431      }
2432  }
2433  
insn_get(CPUX86State * env,DisasContext * s,int ot)2434  static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, int ot)
2435  {
2436      uint32_t ret;
2437  
2438      switch(ot) {
2439      case OT_BYTE:
2440          ret = cpu_ldub_code(env, s->pc);
2441          s->pc++;
2442          break;
2443      case OT_WORD:
2444          ret = cpu_lduw_code(env, s->pc);
2445          s->pc += 2;
2446          break;
2447      default:
2448      case OT_LONG:
2449          ret = cpu_ldl_code(env, s->pc);
2450          s->pc += 4;
2451          break;
2452      }
2453      return ret;
2454  }
2455  
insn_const_size(unsigned int ot)2456  static inline int insn_const_size(unsigned int ot)
2457  {
2458      if (ot <= OT_LONG)
2459          return 1 << ot;
2460      else
2461          return 4;
2462  }
2463  
gen_goto_tb(DisasContext * s,int tb_num,target_ulong eip)2464  static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2465  {
2466      TranslationBlock *tb;
2467      target_ulong pc;
2468  
2469      pc = s->cs_base + eip;
2470      tb = s->tb;
2471      /* NOTE: we handle the case where the TB spans two pages here */
2472      if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2473          (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
2474          /* jump to same page: we can use a direct jump */
2475          tcg_gen_goto_tb(tb_num);
2476          gen_jmp_im(eip);
2477          tcg_gen_exit_tb((uintptr_t)tb + tb_num);
2478      } else {
2479          /* jump to another page: currently not optimized */
2480          gen_jmp_im(eip);
2481          gen_eob(s);
2482      }
2483  }
2484  
gen_jcc(DisasContext * s,int b,target_ulong val,target_ulong next_eip)2485  static inline void gen_jcc(DisasContext *s, int b,
2486                             target_ulong val, target_ulong next_eip)
2487  {
2488      int l1, l2;
2489  
2490      if (s->jmp_opt) {
2491          gen_update_cc_op(s);
2492          l1 = gen_new_label();
2493          gen_jcc1(s, b, l1);
2494          set_cc_op(s, CC_OP_DYNAMIC);
2495  
2496          gen_goto_tb(s, 0, next_eip);
2497  
2498          gen_set_label(l1);
2499          gen_goto_tb(s, 1, val);
2500          s->is_jmp = 3;
2501      } else {
2502          l1 = gen_new_label();
2503          l2 = gen_new_label();
2504          gen_jcc1(s, b, l1);
2505  
2506          gen_jmp_im(next_eip);
2507          tcg_gen_br(l2);
2508  
2509          gen_set_label(l1);
2510          gen_jmp_im(val);
2511          gen_set_label(l2);
2512          gen_eob(s);
2513      }
2514  }
2515  
gen_setcc(DisasContext * s,int b)2516  static void gen_setcc(DisasContext *s, int b)
2517  {
2518      int inv, jcc_op, l1;
2519      TCGv t0;
2520  
2521      if (is_fast_jcc_case(s, b)) {
2522          /* nominal case: we use a jump */
2523          /* XXX: make it faster by adding new instructions in TCG */
2524          t0 = tcg_temp_local_new();
2525          tcg_gen_movi_tl(t0, 0);
2526          l1 = gen_new_label();
2527          gen_jcc1(s, b ^ 1, l1);
2528          tcg_gen_movi_tl(t0, 1);
2529          gen_set_label(l1);
2530          tcg_gen_mov_tl(cpu_T[0], t0);
2531          tcg_temp_free(t0);
2532      } else {
2533          /* slow case: it is more efficient not to generate a jump,
2534             although it is questionnable whether this optimization is
2535             worth to */
2536          inv = b & 1;
2537          jcc_op = (b >> 1) & 7;
2538          gen_setcc_slow(s, jcc_op, cpu_T[0], inv);
2539      }
2540  }
2541  
gen_op_movl_T0_seg(int seg_reg)2542  static inline void gen_op_movl_T0_seg(int seg_reg)
2543  {
2544      tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
2545                       offsetof(CPUX86State,segs[seg_reg].selector));
2546  }
2547  
gen_op_movl_seg_T0_vm(int seg_reg)2548  static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2549  {
2550      tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
2551      tcg_gen_st32_tl(cpu_T[0], cpu_env,
2552                      offsetof(CPUX86State,segs[seg_reg].selector));
2553      tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
2554      tcg_gen_st_tl(cpu_T[0], cpu_env,
2555                    offsetof(CPUX86State,segs[seg_reg].base));
2556  }
2557  
2558  /* move T0 to seg_reg and compute if the CPU state may change. Never
2559     call this function with seg_reg == R_CS */
gen_movl_seg_T0(DisasContext * s,int seg_reg,target_ulong cur_eip)2560  static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
2561  {
2562      if (s->pe && !s->vm86) {
2563          /* XXX: optimize by finding processor state dynamically */
2564          gen_update_cc_op(s);
2565          gen_jmp_im(cur_eip);
2566          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2567          gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2568          /* abort translation because the addseg value may change or
2569             because ss32 may change. For R_SS, translation must always
2570             stop as a special handling must be done to disable hardware
2571             interrupts for the next instruction */
2572          if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2573              s->is_jmp = 3;
2574      } else {
2575          gen_op_movl_seg_T0_vm(seg_reg);
2576          if (seg_reg == R_SS)
2577              s->is_jmp = 3;
2578      }
2579  }
2580  
svm_is_rep(int prefixes)2581  static inline int svm_is_rep(int prefixes)
2582  {
2583      return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2584  }
2585  
2586  static inline void
gen_svm_check_intercept_param(DisasContext * s,target_ulong pc_start,uint32_t type,uint64_t param)2587  gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2588                                uint32_t type, uint64_t param)
2589  {
2590      /* no SVM activated; fast case */
2591      if (likely(!(s->flags & HF_SVMI_MASK)))
2592          return;
2593      gen_update_cc_op(s);
2594      gen_jmp_im(pc_start - s->cs_base);
2595      gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2596                                           tcg_const_i64(param));
2597  }
2598  
2599  static inline void
gen_svm_check_intercept(DisasContext * s,target_ulong pc_start,uint64_t type)2600  gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2601  {
2602      gen_svm_check_intercept_param(s, pc_start, type, 0);
2603  }
2604  
gen_stack_update(DisasContext * s,int addend)2605  static inline void gen_stack_update(DisasContext *s, int addend)
2606  {
2607  #ifdef TARGET_X86_64
2608      if (CODE64(s)) {
2609          gen_op_add_reg_im(2, R_ESP, addend);
2610      } else
2611  #endif
2612      if (s->ss32) {
2613          gen_op_add_reg_im(1, R_ESP, addend);
2614      } else {
2615          gen_op_add_reg_im(0, R_ESP, addend);
2616      }
2617  }
2618  
2619  /* generate a push. It depends on ss32, addseg and dflag */
gen_push_T0(DisasContext * s)2620  static void gen_push_T0(DisasContext *s)
2621  {
2622  #ifdef TARGET_X86_64
2623      if (CODE64(s)) {
2624          gen_op_movq_A0_reg(R_ESP);
2625          if (s->dflag) {
2626              gen_op_addq_A0_im(-8);
2627              gen_op_st_T0_A0(OT_QUAD + s->mem_index);
2628          } else {
2629              gen_op_addq_A0_im(-2);
2630              gen_op_st_T0_A0(OT_WORD + s->mem_index);
2631          }
2632          gen_op_mov_reg_A0(2, R_ESP);
2633      } else
2634  #endif
2635      {
2636          gen_op_movl_A0_reg(R_ESP);
2637          if (!s->dflag)
2638              gen_op_addl_A0_im(-2);
2639          else
2640              gen_op_addl_A0_im(-4);
2641          if (s->ss32) {
2642              if (s->addseg) {
2643                  tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2644                  gen_op_addl_A0_seg(s, R_SS);
2645              }
2646          } else {
2647              gen_op_andl_A0_ffff();
2648              tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2649              gen_op_addl_A0_seg(s, R_SS);
2650          }
2651          gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
2652          if (s->ss32 && !s->addseg)
2653              gen_op_mov_reg_A0(1, R_ESP);
2654          else
2655              gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
2656      }
2657  }
2658  
2659  /* generate a push. It depends on ss32, addseg and dflag */
2660  /* slower version for T1, only used for call Ev */
gen_push_T1(DisasContext * s)2661  static void gen_push_T1(DisasContext *s)
2662  {
2663  #ifdef TARGET_X86_64
2664      if (CODE64(s)) {
2665          gen_op_movq_A0_reg(R_ESP);
2666          if (s->dflag) {
2667              gen_op_addq_A0_im(-8);
2668              gen_op_st_T1_A0(OT_QUAD + s->mem_index);
2669          } else {
2670              gen_op_addq_A0_im(-2);
2671              gen_op_st_T0_A0(OT_WORD + s->mem_index);
2672          }
2673          gen_op_mov_reg_A0(2, R_ESP);
2674      } else
2675  #endif
2676      {
2677          gen_op_movl_A0_reg(R_ESP);
2678          if (!s->dflag)
2679              gen_op_addl_A0_im(-2);
2680          else
2681              gen_op_addl_A0_im(-4);
2682          if (s->ss32) {
2683              if (s->addseg) {
2684                  gen_op_addl_A0_seg(s, R_SS);
2685              }
2686          } else {
2687              gen_op_andl_A0_ffff();
2688              gen_op_addl_A0_seg(s, R_SS);
2689          }
2690          gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
2691  
2692          if (s->ss32 && !s->addseg)
2693              gen_op_mov_reg_A0(1, R_ESP);
2694          else
2695              gen_stack_update(s, (-2) << s->dflag);
2696      }
2697  }
2698  
2699  /* two step pop is necessary for precise exceptions */
gen_pop_T0(DisasContext * s)2700  static void gen_pop_T0(DisasContext *s)
2701  {
2702  #ifdef TARGET_X86_64
2703      if (CODE64(s)) {
2704          gen_op_movq_A0_reg(R_ESP);
2705          gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
2706      } else
2707  #endif
2708      {
2709          gen_op_movl_A0_reg(R_ESP);
2710          if (s->ss32) {
2711              if (s->addseg)
2712                  gen_op_addl_A0_seg(s, R_SS);
2713          } else {
2714              gen_op_andl_A0_ffff();
2715              gen_op_addl_A0_seg(s, R_SS);
2716          }
2717          gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
2718      }
2719  }
2720  
gen_pop_update(DisasContext * s)2721  static void gen_pop_update(DisasContext *s)
2722  {
2723  #ifdef TARGET_X86_64
2724      if (CODE64(s) && s->dflag) {
2725          gen_stack_update(s, 8);
2726      } else
2727  #endif
2728      {
2729          gen_stack_update(s, 2 << s->dflag);
2730      }
2731  }
2732  
gen_stack_A0(DisasContext * s)2733  static void gen_stack_A0(DisasContext *s)
2734  {
2735      gen_op_movl_A0_reg(R_ESP);
2736      if (!s->ss32)
2737          gen_op_andl_A0_ffff();
2738      tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2739      if (s->addseg)
2740          gen_op_addl_A0_seg(s, R_SS);
2741  }
2742  
2743  /* NOTE: wrap around in 16 bit not fully handled */
gen_pusha(DisasContext * s)2744  static void gen_pusha(DisasContext *s)
2745  {
2746      int i;
2747      gen_op_movl_A0_reg(R_ESP);
2748      gen_op_addl_A0_im(-16 <<  s->dflag);
2749      if (!s->ss32)
2750          gen_op_andl_A0_ffff();
2751      tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2752      if (s->addseg)
2753          gen_op_addl_A0_seg(s, R_SS);
2754      for(i = 0;i < 8; i++) {
2755          gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
2756          gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
2757          gen_op_addl_A0_im(2 <<  s->dflag);
2758      }
2759      gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2760  }
2761  
2762  /* NOTE: wrap around in 16 bit not fully handled */
gen_popa(DisasContext * s)2763  static void gen_popa(DisasContext *s)
2764  {
2765      int i;
2766      gen_op_movl_A0_reg(R_ESP);
2767      if (!s->ss32)
2768          gen_op_andl_A0_ffff();
2769      tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2770      tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
2771      if (s->addseg)
2772          gen_op_addl_A0_seg(s, R_SS);
2773      for(i = 0;i < 8; i++) {
2774          /* ESP is not reloaded */
2775          if (i != 3) {
2776              gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
2777              gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
2778          }
2779          gen_op_addl_A0_im(2 <<  s->dflag);
2780      }
2781      gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2782  }
2783  
gen_enter(DisasContext * s,int esp_addend,int level)2784  static void gen_enter(DisasContext *s, int esp_addend, int level)
2785  {
2786      int ot, opsize;
2787  
2788      level &= 0x1f;
2789  #ifdef TARGET_X86_64
2790      if (CODE64(s)) {
2791          ot = s->dflag ? OT_QUAD : OT_WORD;
2792          opsize = 1 << ot;
2793  
2794          gen_op_movl_A0_reg(R_ESP);
2795          gen_op_addq_A0_im(-opsize);
2796          tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2797  
2798          /* push bp */
2799          gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2800          gen_op_st_T0_A0(ot + s->mem_index);
2801          if (level) {
2802              /* XXX: must save state */
2803              gen_helper_enter64_level(cpu_env, tcg_const_i32(level),
2804                                       tcg_const_i32((ot == OT_QUAD)),
2805                                       cpu_T[1]);
2806          }
2807          gen_op_mov_reg_T1(ot, R_EBP);
2808          tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2809          gen_op_mov_reg_T1(OT_QUAD, R_ESP);
2810      } else
2811  #endif
2812      {
2813          ot = s->dflag + OT_WORD;
2814          opsize = 2 << s->dflag;
2815  
2816          gen_op_movl_A0_reg(R_ESP);
2817          gen_op_addl_A0_im(-opsize);
2818          if (!s->ss32)
2819              gen_op_andl_A0_ffff();
2820          tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2821          if (s->addseg)
2822              gen_op_addl_A0_seg(s, R_SS);
2823          /* push bp */
2824          gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2825          gen_op_st_T0_A0(ot + s->mem_index);
2826          if (level) {
2827              /* XXX: must save state */
2828              gen_helper_enter_level(cpu_env, tcg_const_i32(level),
2829                                     tcg_const_i32(s->dflag),
2830                                     cpu_T[1]);
2831          }
2832          gen_op_mov_reg_T1(ot, R_EBP);
2833          tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2834          gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2835      }
2836  }
2837  
gen_exception(DisasContext * s,int trapno,target_ulong cur_eip)2838  static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2839  {
2840      gen_update_cc_op(s);
2841      gen_jmp_im(cur_eip);
2842      gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2843      s->is_jmp = 3;
2844  }
2845  
2846  /* an interrupt is different from an exception because of the
2847     privilege checks */
gen_interrupt(DisasContext * s,int intno,target_ulong cur_eip,target_ulong next_eip)2848  static void gen_interrupt(DisasContext *s, int intno,
2849                            target_ulong cur_eip, target_ulong next_eip)
2850  {
2851      gen_update_cc_op(s);
2852      gen_jmp_im(cur_eip);
2853      gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2854                                 tcg_const_i32(next_eip - cur_eip));
2855      s->is_jmp = 3;
2856  }
2857  
gen_debug(DisasContext * s,target_ulong cur_eip)2858  static void gen_debug(DisasContext *s, target_ulong cur_eip)
2859  {
2860      gen_update_cc_op(s);
2861      gen_jmp_im(cur_eip);
2862      gen_helper_debug(cpu_env);
2863      s->is_jmp = 3;
2864  }
2865  
2866  /* generate a generic end of block. Trace exception is also generated
2867     if needed */
gen_eob(DisasContext * s)2868  static void gen_eob(DisasContext *s)
2869  {
2870      gen_update_cc_op(s);
2871      if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2872          gen_helper_reset_inhibit_irq(cpu_env);
2873      }
2874      if (s->tb->flags & HF_RF_MASK) {
2875          gen_helper_reset_rf(cpu_env);
2876      }
2877      if (s->singlestep_enabled) {
2878          gen_helper_debug(cpu_env);
2879      } else if (s->tf) {
2880  	gen_helper_single_step(cpu_env);
2881      } else {
2882          tcg_gen_exit_tb(0);
2883      }
2884      s->is_jmp = 3;
2885  }
2886  
2887  /* generate a jump to eip. No segment change must happen before as a
2888     direct call to the next block may occur */
gen_jmp_tb(DisasContext * s,target_ulong eip,int tb_num)2889  static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2890  {
2891      if (s->jmp_opt) {
2892          gen_update_cc_op(s);
2893          gen_goto_tb(s, tb_num, eip);
2894          s->is_jmp = 3;
2895      } else {
2896          gen_jmp_im(eip);
2897          gen_eob(s);
2898      }
2899  }
2900  
gen_jmp(DisasContext * s,target_ulong eip)2901  static void gen_jmp(DisasContext *s, target_ulong eip)
2902  {
2903      gen_jmp_tb(s, eip, 0);
2904  }
2905  
gen_ldq_env_A0(int idx,int offset)2906  static inline void gen_ldq_env_A0(int idx, int offset)
2907  {
2908      int mem_index = (idx >> 2) - 1;
2909      tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2910      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2911  }
2912  
gen_stq_env_A0(int idx,int offset)2913  static inline void gen_stq_env_A0(int idx, int offset)
2914  {
2915      int mem_index = (idx >> 2) - 1;
2916      tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2917      tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2918  }
2919  
gen_ldo_env_A0(int idx,int offset)2920  static inline void gen_ldo_env_A0(int idx, int offset)
2921  {
2922      int mem_index = (idx >> 2) - 1;
2923      tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2924      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2925      tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2926      tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2927      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2928  }
2929  
gen_sto_env_A0(int idx,int offset)2930  static inline void gen_sto_env_A0(int idx, int offset)
2931  {
2932      int mem_index = (idx >> 2) - 1;
2933      tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2934      tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2935      tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2936      tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2937      tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2938  }
2939  
gen_op_movo(int d_offset,int s_offset)2940  static inline void gen_op_movo(int d_offset, int s_offset)
2941  {
2942      tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2943      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2944      tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2945      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2946  }
2947  
gen_op_movq(int d_offset,int s_offset)2948  static inline void gen_op_movq(int d_offset, int s_offset)
2949  {
2950      tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2951      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2952  }
2953  
gen_op_movl(int d_offset,int s_offset)2954  static inline void gen_op_movl(int d_offset, int s_offset)
2955  {
2956      tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2957      tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2958  }
2959  
gen_op_movq_env_0(int d_offset)2960  static inline void gen_op_movq_env_0(int d_offset)
2961  {
2962      tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2963      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2964  }
2965  
2966  typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2967  typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2968  typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2969  typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2970  typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2971  typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2972                                 TCGv_i32 val);
2973  typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2974  typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2975                                 TCGv val);
2976  
2977  #define SSE_SPECIAL ((void *)1)
2978  #define SSE_DUMMY ((void *)2)
2979  
2980  #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2981  #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2982                       gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2983  
2984  static const SSEFunc_0_epp sse_op_table1[256][4] = {
2985      /* 3DNow! extensions */
2986      [0x0e] = { SSE_DUMMY }, /* femms */
2987      [0x0f] = { SSE_DUMMY }, /* pf... */
2988      /* pure SSE operations */
2989      [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2990      [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2991      [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2992      [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2993      [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2994      [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2995      [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2996      [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2997  
2998      [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2999      [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
3000      [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
3001      [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
3002      [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
3003      [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
3004      [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
3005      [0x2f] = { gen_helper_comiss, gen_helper_comisd },
3006      [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
3007      [0x51] = SSE_FOP(sqrt),
3008      [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
3009      [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
3010      [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
3011      [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
3012      [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
3013      [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
3014      [0x58] = SSE_FOP(add),
3015      [0x59] = SSE_FOP(mul),
3016      [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
3017                 gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
3018      [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
3019      [0x5c] = SSE_FOP(sub),
3020      [0x5d] = SSE_FOP(min),
3021      [0x5e] = SSE_FOP(div),
3022      [0x5f] = SSE_FOP(max),
3023  
3024      [0xc2] = SSE_FOP(cmpeq),
3025      [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
3026                 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
3027  
3028      /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX.  */
3029      [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
3030      [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
3031  
3032      /* MMX ops and their SSE extensions */
3033      [0x60] = MMX_OP2(punpcklbw),
3034      [0x61] = MMX_OP2(punpcklwd),
3035      [0x62] = MMX_OP2(punpckldq),
3036      [0x63] = MMX_OP2(packsswb),
3037      [0x64] = MMX_OP2(pcmpgtb),
3038      [0x65] = MMX_OP2(pcmpgtw),
3039      [0x66] = MMX_OP2(pcmpgtl),
3040      [0x67] = MMX_OP2(packuswb),
3041      [0x68] = MMX_OP2(punpckhbw),
3042      [0x69] = MMX_OP2(punpckhwd),
3043      [0x6a] = MMX_OP2(punpckhdq),
3044      [0x6b] = MMX_OP2(packssdw),
3045      [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
3046      [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
3047      [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
3048      [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
3049      [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
3050                 (SSEFunc_0_epp)gen_helper_pshufd_xmm,
3051                 (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
3052                 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
3053      [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
3054      [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
3055      [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
3056      [0x74] = MMX_OP2(pcmpeqb),
3057      [0x75] = MMX_OP2(pcmpeqw),
3058      [0x76] = MMX_OP2(pcmpeql),
3059      [0x77] = { SSE_DUMMY }, /* emms */
3060      [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
3061      [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
3062      [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
3063      [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
3064      [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
3065      [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
3066      [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
3067      [0xd1] = MMX_OP2(psrlw),
3068      [0xd2] = MMX_OP2(psrld),
3069      [0xd3] = MMX_OP2(psrlq),
3070      [0xd4] = MMX_OP2(paddq),
3071      [0xd5] = MMX_OP2(pmullw),
3072      [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
3073      [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
3074      [0xd8] = MMX_OP2(psubusb),
3075      [0xd9] = MMX_OP2(psubusw),
3076      [0xda] = MMX_OP2(pminub),
3077      [0xdb] = MMX_OP2(pand),
3078      [0xdc] = MMX_OP2(paddusb),
3079      [0xdd] = MMX_OP2(paddusw),
3080      [0xde] = MMX_OP2(pmaxub),
3081      [0xdf] = MMX_OP2(pandn),
3082      [0xe0] = MMX_OP2(pavgb),
3083      [0xe1] = MMX_OP2(psraw),
3084      [0xe2] = MMX_OP2(psrad),
3085      [0xe3] = MMX_OP2(pavgw),
3086      [0xe4] = MMX_OP2(pmulhuw),
3087      [0xe5] = MMX_OP2(pmulhw),
3088      [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
3089      [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
3090      [0xe8] = MMX_OP2(psubsb),
3091      [0xe9] = MMX_OP2(psubsw),
3092      [0xea] = MMX_OP2(pminsw),
3093      [0xeb] = MMX_OP2(por),
3094      [0xec] = MMX_OP2(paddsb),
3095      [0xed] = MMX_OP2(paddsw),
3096      [0xee] = MMX_OP2(pmaxsw),
3097      [0xef] = MMX_OP2(pxor),
3098      [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
3099      [0xf1] = MMX_OP2(psllw),
3100      [0xf2] = MMX_OP2(pslld),
3101      [0xf3] = MMX_OP2(psllq),
3102      [0xf4] = MMX_OP2(pmuludq),
3103      [0xf5] = MMX_OP2(pmaddwd),
3104      [0xf6] = MMX_OP2(psadbw),
3105      [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
3106                 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
3107      [0xf8] = MMX_OP2(psubb),
3108      [0xf9] = MMX_OP2(psubw),
3109      [0xfa] = MMX_OP2(psubl),
3110      [0xfb] = MMX_OP2(psubq),
3111      [0xfc] = MMX_OP2(paddb),
3112      [0xfd] = MMX_OP2(paddw),
3113      [0xfe] = MMX_OP2(paddl),
3114  };
3115  
3116  static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
3117      [0 + 2] = MMX_OP2(psrlw),
3118      [0 + 4] = MMX_OP2(psraw),
3119      [0 + 6] = MMX_OP2(psllw),
3120      [8 + 2] = MMX_OP2(psrld),
3121      [8 + 4] = MMX_OP2(psrad),
3122      [8 + 6] = MMX_OP2(pslld),
3123      [16 + 2] = MMX_OP2(psrlq),
3124      [16 + 3] = { NULL, gen_helper_psrldq_xmm },
3125      [16 + 6] = MMX_OP2(psllq),
3126      [16 + 7] = { NULL, gen_helper_pslldq_xmm },
3127  };
3128  
3129  static const SSEFunc_0_epi sse_op_table3ai[] = {
3130      gen_helper_cvtsi2ss,
3131      gen_helper_cvtsi2sd
3132  };
3133  
3134  #ifdef TARGET_X86_64
3135  static const SSEFunc_0_epl sse_op_table3aq[] = {
3136      gen_helper_cvtsq2ss,
3137      gen_helper_cvtsq2sd
3138  };
3139  #endif
3140  
3141  static const SSEFunc_i_ep sse_op_table3bi[] = {
3142      gen_helper_cvttss2si,
3143      gen_helper_cvtss2si,
3144      gen_helper_cvttsd2si,
3145      gen_helper_cvtsd2si
3146  };
3147  
3148  #ifdef TARGET_X86_64
3149  static const SSEFunc_l_ep sse_op_table3bq[] = {
3150      gen_helper_cvttss2sq,
3151      gen_helper_cvtss2sq,
3152      gen_helper_cvttsd2sq,
3153      gen_helper_cvtsd2sq
3154  };
3155  #endif
3156  
3157  static const SSEFunc_0_epp sse_op_table4[8][4] = {
3158      SSE_FOP(cmpeq),
3159      SSE_FOP(cmplt),
3160      SSE_FOP(cmple),
3161      SSE_FOP(cmpunord),
3162      SSE_FOP(cmpneq),
3163      SSE_FOP(cmpnlt),
3164      SSE_FOP(cmpnle),
3165      SSE_FOP(cmpord),
3166  };
3167  
3168  static const SSEFunc_0_epp sse_op_table5[256] = {
3169      [0x0c] = gen_helper_pi2fw,
3170      [0x0d] = gen_helper_pi2fd,
3171      [0x1c] = gen_helper_pf2iw,
3172      [0x1d] = gen_helper_pf2id,
3173      [0x8a] = gen_helper_pfnacc,
3174      [0x8e] = gen_helper_pfpnacc,
3175      [0x90] = gen_helper_pfcmpge,
3176      [0x94] = gen_helper_pfmin,
3177      [0x96] = gen_helper_pfrcp,
3178      [0x97] = gen_helper_pfrsqrt,
3179      [0x9a] = gen_helper_pfsub,
3180      [0x9e] = gen_helper_pfadd,
3181      [0xa0] = gen_helper_pfcmpgt,
3182      [0xa4] = gen_helper_pfmax,
3183      [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
3184      [0xa7] = gen_helper_movq, /* pfrsqit1 */
3185      [0xaa] = gen_helper_pfsubr,
3186      [0xae] = gen_helper_pfacc,
3187      [0xb0] = gen_helper_pfcmpeq,
3188      [0xb4] = gen_helper_pfmul,
3189      [0xb6] = gen_helper_movq, /* pfrcpit2 */
3190      [0xb7] = gen_helper_pmulhrw_mmx,
3191      [0xbb] = gen_helper_pswapd,
3192      [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
3193  };
3194  
3195  struct SSEOpHelper_epp {
3196      SSEFunc_0_epp op[2];
3197      uint32_t ext_mask;
3198  };
3199  
3200  struct SSEOpHelper_eppi {
3201      SSEFunc_0_eppi op[2];
3202      uint32_t ext_mask;
3203  };
3204  
3205  #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3206  #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3207  #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3208  #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3209  static const struct SSEOpHelper_epp sse_op_table6[256] = {
3210      [0x00] = SSSE3_OP(pshufb),
3211      [0x01] = SSSE3_OP(phaddw),
3212      [0x02] = SSSE3_OP(phaddd),
3213      [0x03] = SSSE3_OP(phaddsw),
3214      [0x04] = SSSE3_OP(pmaddubsw),
3215      [0x05] = SSSE3_OP(phsubw),
3216      [0x06] = SSSE3_OP(phsubd),
3217      [0x07] = SSSE3_OP(phsubsw),
3218      [0x08] = SSSE3_OP(psignb),
3219      [0x09] = SSSE3_OP(psignw),
3220      [0x0a] = SSSE3_OP(psignd),
3221      [0x0b] = SSSE3_OP(pmulhrsw),
3222      [0x10] = SSE41_OP(pblendvb),
3223      [0x14] = SSE41_OP(blendvps),
3224      [0x15] = SSE41_OP(blendvpd),
3225      [0x17] = SSE41_OP(ptest),
3226      [0x1c] = SSSE3_OP(pabsb),
3227      [0x1d] = SSSE3_OP(pabsw),
3228      [0x1e] = SSSE3_OP(pabsd),
3229      [0x20] = SSE41_OP(pmovsxbw),
3230      [0x21] = SSE41_OP(pmovsxbd),
3231      [0x22] = SSE41_OP(pmovsxbq),
3232      [0x23] = SSE41_OP(pmovsxwd),
3233      [0x24] = SSE41_OP(pmovsxwq),
3234      [0x25] = SSE41_OP(pmovsxdq),
3235      [0x28] = SSE41_OP(pmuldq),
3236      [0x29] = SSE41_OP(pcmpeqq),
3237      [0x2a] = SSE41_SPECIAL, /* movntqda */
3238      [0x2b] = SSE41_OP(packusdw),
3239      [0x30] = SSE41_OP(pmovzxbw),
3240      [0x31] = SSE41_OP(pmovzxbd),
3241      [0x32] = SSE41_OP(pmovzxbq),
3242      [0x33] = SSE41_OP(pmovzxwd),
3243      [0x34] = SSE41_OP(pmovzxwq),
3244      [0x35] = SSE41_OP(pmovzxdq),
3245      [0x37] = SSE42_OP(pcmpgtq),
3246      [0x38] = SSE41_OP(pminsb),
3247      [0x39] = SSE41_OP(pminsd),
3248      [0x3a] = SSE41_OP(pminuw),
3249      [0x3b] = SSE41_OP(pminud),
3250      [0x3c] = SSE41_OP(pmaxsb),
3251      [0x3d] = SSE41_OP(pmaxsd),
3252      [0x3e] = SSE41_OP(pmaxuw),
3253      [0x3f] = SSE41_OP(pmaxud),
3254      [0x40] = SSE41_OP(pmulld),
3255      [0x41] = SSE41_OP(phminposuw),
3256  };
3257  
3258  static const struct SSEOpHelper_eppi sse_op_table7[256] = {
3259      [0x08] = SSE41_OP(roundps),
3260      [0x09] = SSE41_OP(roundpd),
3261      [0x0a] = SSE41_OP(roundss),
3262      [0x0b] = SSE41_OP(roundsd),
3263      [0x0c] = SSE41_OP(blendps),
3264      [0x0d] = SSE41_OP(blendpd),
3265      [0x0e] = SSE41_OP(pblendw),
3266      [0x0f] = SSSE3_OP(palignr),
3267      [0x14] = SSE41_SPECIAL, /* pextrb */
3268      [0x15] = SSE41_SPECIAL, /* pextrw */
3269      [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
3270      [0x17] = SSE41_SPECIAL, /* extractps */
3271      [0x20] = SSE41_SPECIAL, /* pinsrb */
3272      [0x21] = SSE41_SPECIAL, /* insertps */
3273      [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
3274      [0x40] = SSE41_OP(dpps),
3275      [0x41] = SSE41_OP(dppd),
3276      [0x42] = SSE41_OP(mpsadbw),
3277      [0x60] = SSE42_OP(pcmpestrm),
3278      [0x61] = SSE42_OP(pcmpestri),
3279      [0x62] = SSE42_OP(pcmpistrm),
3280      [0x63] = SSE42_OP(pcmpistri),
3281  };
3282  
gen_sse(CPUX86State * env,DisasContext * s,int b,target_ulong pc_start,int rex_r)3283  static void gen_sse(CPUX86State *env, DisasContext *s, int b,
3284                      target_ulong pc_start, int rex_r)
3285  {
3286      int b1, op1_offset, op2_offset, is_xmm, val, ot;
3287      int modrm, mod, rm, reg, reg_addr, offset_addr;
3288      SSEFunc_0_epp sse_fn_epp;
3289      SSEFunc_0_eppi sse_fn_eppi;
3290      SSEFunc_0_ppi sse_fn_ppi;
3291      SSEFunc_0_eppt sse_fn_eppt;
3292  
3293      b &= 0xff;
3294      if (s->prefix & PREFIX_DATA)
3295          b1 = 1;
3296      else if (s->prefix & PREFIX_REPZ)
3297          b1 = 2;
3298      else if (s->prefix & PREFIX_REPNZ)
3299          b1 = 3;
3300      else
3301          b1 = 0;
3302      sse_fn_epp = sse_op_table1[b][b1];
3303      if (!sse_fn_epp) {
3304          goto illegal_op;
3305      }
3306      if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3307          is_xmm = 1;
3308      } else {
3309          if (b1 == 0) {
3310              /* MMX case */
3311              is_xmm = 0;
3312          } else {
3313              is_xmm = 1;
3314          }
3315      }
3316      /* simple MMX/SSE operation */
3317      if (s->flags & HF_TS_MASK) {
3318          gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3319          return;
3320      }
3321      if (s->flags & HF_EM_MASK) {
3322      illegal_op:
3323          gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
3324          return;
3325      }
3326      if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
3327          if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))
3328              goto illegal_op;
3329      if (b == 0x0e) {
3330          if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
3331              goto illegal_op;
3332          /* femms */
3333          gen_helper_emms(cpu_env);
3334          return;
3335      }
3336      if (b == 0x77) {
3337          /* emms */
3338          gen_helper_emms(cpu_env);
3339          return;
3340      }
3341      /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3342         the static cpu state) */
3343      if (!is_xmm) {
3344          gen_helper_enter_mmx(cpu_env);
3345      }
3346  
3347      modrm = cpu_ldub_code(env, s->pc++);
3348      reg = ((modrm >> 3) & 7);
3349      if (is_xmm)
3350          reg |= rex_r;
3351      mod = (modrm >> 6) & 3;
3352      if (sse_fn_epp == SSE_SPECIAL) {
3353          b |= (b1 << 8);
3354          switch(b) {
3355          case 0x0e7: /* movntq */
3356              if (mod == 3)
3357                  goto illegal_op;
3358              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3359              gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3360              break;
3361          case 0x1e7: /* movntdq */
3362          case 0x02b: /* movntps */
3363          case 0x12b: /* movntps */
3364          case 0x3f0: /* lddqu */
3365              if (mod == 3)
3366                  goto illegal_op;
3367              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3368              gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3369              break;
3370          case 0x6e: /* movd mm, ea */
3371  #ifdef TARGET_X86_64
3372              if (s->dflag == 2) {
3373                  gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 0);
3374                  tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3375              } else
3376  #endif
3377              {
3378                  gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 0);
3379                  tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3380                                   offsetof(CPUX86State,fpregs[reg].mmx));
3381                  tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3382                  gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3383              }
3384              break;
3385          case 0x16e: /* movd xmm, ea */
3386  #ifdef TARGET_X86_64
3387              if (s->dflag == 2) {
3388                  gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 0);
3389                  tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3390                                   offsetof(CPUX86State,xmm_regs[reg]));
3391                  gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]);
3392              } else
3393  #endif
3394              {
3395                  gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 0);
3396                  tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3397                                   offsetof(CPUX86State,xmm_regs[reg]));
3398                  tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3399                  gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3400              }
3401              break;
3402          case 0x6f: /* movq mm, ea */
3403              if (mod != 3) {
3404                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3405                  gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3406              } else {
3407                  rm = (modrm & 7);
3408                  tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3409                                 offsetof(CPUX86State,fpregs[rm].mmx));
3410                  tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3411                                 offsetof(CPUX86State,fpregs[reg].mmx));
3412              }
3413              break;
3414          case 0x010: /* movups */
3415          case 0x110: /* movupd */
3416          case 0x028: /* movaps */
3417          case 0x128: /* movapd */
3418          case 0x16f: /* movdqa xmm, ea */
3419          case 0x26f: /* movdqu xmm, ea */
3420              if (mod != 3) {
3421                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3422                  gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3423              } else {
3424                  rm = (modrm & 7) | REX_B(s);
3425                  gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3426                              offsetof(CPUX86State,xmm_regs[rm]));
3427              }
3428              break;
3429          case 0x210: /* movss xmm, ea */
3430              if (mod != 3) {
3431                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3432                  gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3433                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3434                  gen_op_movl_T0_0();
3435                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3436                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3437                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3438              } else {
3439                  rm = (modrm & 7) | REX_B(s);
3440                  gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3441                              offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3442              }
3443              break;
3444          case 0x310: /* movsd xmm, ea */
3445              if (mod != 3) {
3446                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3447                  gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3448                  gen_op_movl_T0_0();
3449                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3450                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3451              } else {
3452                  rm = (modrm & 7) | REX_B(s);
3453                  gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3454                              offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3455              }
3456              break;
3457          case 0x012: /* movlps */
3458          case 0x112: /* movlpd */
3459              if (mod != 3) {
3460                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3461                  gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3462              } else {
3463                  /* movhlps */
3464                  rm = (modrm & 7) | REX_B(s);
3465                  gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3466                              offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3467              }
3468              break;
3469          case 0x212: /* movsldup */
3470              if (mod != 3) {
3471                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3472                  gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3473              } else {
3474                  rm = (modrm & 7) | REX_B(s);
3475                  gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3476                              offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3477                  gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3478                              offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
3479              }
3480              gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3481                          offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3482              gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3483                          offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3484              break;
3485          case 0x312: /* movddup */
3486              if (mod != 3) {
3487                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3488                  gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3489              } else {
3490                  rm = (modrm & 7) | REX_B(s);
3491                  gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3492                              offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3493              }
3494              gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3495                          offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3496              break;
3497          case 0x016: /* movhps */
3498          case 0x116: /* movhpd */
3499              if (mod != 3) {
3500                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3501                  gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3502              } else {
3503                  /* movlhps */
3504                  rm = (modrm & 7) | REX_B(s);
3505                  gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3506                              offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3507              }
3508              break;
3509          case 0x216: /* movshdup */
3510              if (mod != 3) {
3511                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3512                  gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3513              } else {
3514                  rm = (modrm & 7) | REX_B(s);
3515                  gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3516                              offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
3517                  gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3518                              offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
3519              }
3520              gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3521                          offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3522              gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3523                          offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3524              break;
3525          case 0x7e: /* movd ea, mm */
3526  #ifdef TARGET_X86_64
3527              if (s->dflag == 2) {
3528                  tcg_gen_ld_i64(cpu_T[0], cpu_env,
3529                                 offsetof(CPUX86State,fpregs[reg].mmx));
3530                  gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 1);
3531              } else
3532  #endif
3533              {
3534                  tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
3535                                   offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3536                  gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 1);
3537              }
3538              break;
3539          case 0x17e: /* movd ea, xmm */
3540  #ifdef TARGET_X86_64
3541              if (s->dflag == 2) {
3542                  tcg_gen_ld_i64(cpu_T[0], cpu_env,
3543                                 offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3544                  gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 1);
3545              } else
3546  #endif
3547              {
3548                  tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
3549                                   offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3550                  gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 1);
3551              }
3552              break;
3553          case 0x27e: /* movq xmm, ea */
3554              if (mod != 3) {
3555                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3556                  gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3557              } else {
3558                  rm = (modrm & 7) | REX_B(s);
3559                  gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3560                              offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3561              }
3562              gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3563              break;
3564          case 0x7f: /* movq ea, mm */
3565              if (mod != 3) {
3566                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3567                  gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
3568              } else {
3569                  rm = (modrm & 7);
3570                  gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3571                              offsetof(CPUX86State,fpregs[reg].mmx));
3572              }
3573              break;
3574          case 0x011: /* movups */
3575          case 0x111: /* movupd */
3576          case 0x029: /* movaps */
3577          case 0x129: /* movapd */
3578          case 0x17f: /* movdqa ea, xmm */
3579          case 0x27f: /* movdqu ea, xmm */
3580              if (mod != 3) {
3581                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3582                  gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
3583              } else {
3584                  rm = (modrm & 7) | REX_B(s);
3585                  gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3586                              offsetof(CPUX86State,xmm_regs[reg]));
3587              }
3588              break;
3589          case 0x211: /* movss ea, xmm */
3590              if (mod != 3) {
3591                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3592                  tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3593                  gen_op_st_T0_A0(OT_LONG + s->mem_index);
3594              } else {
3595                  rm = (modrm & 7) | REX_B(s);
3596                  gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
3597                              offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3598              }
3599              break;
3600          case 0x311: /* movsd ea, xmm */
3601              if (mod != 3) {
3602                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3603                  gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3604              } else {
3605                  rm = (modrm & 7) | REX_B(s);
3606                  gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3607                              offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3608              }
3609              break;
3610          case 0x013: /* movlps */
3611          case 0x113: /* movlpd */
3612              if (mod != 3) {
3613                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3614                  gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3615              } else {
3616                  goto illegal_op;
3617              }
3618              break;
3619          case 0x017: /* movhps */
3620          case 0x117: /* movhpd */
3621              if (mod != 3) {
3622                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3623                  gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3624              } else {
3625                  goto illegal_op;
3626              }
3627              break;
3628          case 0x71: /* shift mm, im */
3629          case 0x72:
3630          case 0x73:
3631          case 0x171: /* shift xmm, im */
3632          case 0x172:
3633          case 0x173:
3634              if (b1 >= 2) {
3635  	        goto illegal_op;
3636              }
3637              val = cpu_ldub_code(env, s->pc++);
3638              if (is_xmm) {
3639                  gen_op_movl_T0_im(val);
3640                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3641                  gen_op_movl_T0_0();
3642                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1)));
3643                  op1_offset = offsetof(CPUX86State,xmm_t0);
3644              } else {
3645                  gen_op_movl_T0_im(val);
3646                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3647                  gen_op_movl_T0_0();
3648                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3649                  op1_offset = offsetof(CPUX86State,mmx_t0);
3650              }
3651              sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3652                                         (((modrm >> 3)) & 7)][b1];
3653              if (!sse_fn_epp) {
3654                  goto illegal_op;
3655              }
3656              if (is_xmm) {
3657                  rm = (modrm & 7) | REX_B(s);
3658                  op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3659              } else {
3660                  rm = (modrm & 7);
3661                  op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3662              }
3663              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3664              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3665              sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3666              break;
3667          case 0x050: /* movmskps */
3668              rm = (modrm & 7) | REX_B(s);
3669              tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3670                               offsetof(CPUX86State,xmm_regs[rm]));
3671              gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3672              tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3673              gen_op_mov_reg_T0(OT_LONG, reg);
3674              break;
3675          case 0x150: /* movmskpd */
3676              rm = (modrm & 7) | REX_B(s);
3677              tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3678                               offsetof(CPUX86State,xmm_regs[rm]));
3679              gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3680              tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3681              gen_op_mov_reg_T0(OT_LONG, reg);
3682              break;
3683          case 0x02a: /* cvtpi2ps */
3684          case 0x12a: /* cvtpi2pd */
3685              gen_helper_enter_mmx(cpu_env);
3686              if (mod != 3) {
3687                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3688                  op2_offset = offsetof(CPUX86State,mmx_t0);
3689                  gen_ldq_env_A0(s->mem_index, op2_offset);
3690              } else {
3691                  rm = (modrm & 7);
3692                  op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3693              }
3694              op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3695              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3696              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3697              switch(b >> 8) {
3698              case 0x0:
3699                  gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3700                  break;
3701              default:
3702              case 0x1:
3703                  gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3704                  break;
3705              }
3706              break;
3707          case 0x22a: /* cvtsi2ss */
3708          case 0x32a: /* cvtsi2sd */
3709              ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3710              gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3711              op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3712              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3713              if (ot == OT_LONG) {
3714                  SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3715                  tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3716                  sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3717              } else {
3718  #ifdef TARGET_X86_64
3719                  SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3720                  sse_fn_epl(cpu_env, cpu_ptr0, cpu_T[0]);
3721  #else
3722                  goto illegal_op;
3723  #endif
3724              }
3725              break;
3726          case 0x02c: /* cvttps2pi */
3727          case 0x12c: /* cvttpd2pi */
3728          case 0x02d: /* cvtps2pi */
3729          case 0x12d: /* cvtpd2pi */
3730              gen_helper_enter_mmx(cpu_env);
3731              if (mod != 3) {
3732                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3733                  op2_offset = offsetof(CPUX86State,xmm_t0);
3734                  gen_ldo_env_A0(s->mem_index, op2_offset);
3735              } else {
3736                  rm = (modrm & 7) | REX_B(s);
3737                  op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3738              }
3739              op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3740              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3741              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3742              switch(b) {
3743              case 0x02c:
3744                  gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3745                  break;
3746              case 0x12c:
3747                  gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3748                  break;
3749              case 0x02d:
3750                  gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3751                  break;
3752              case 0x12d:
3753                  gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3754                  break;
3755              }
3756              break;
3757          case 0x22c: /* cvttss2si */
3758          case 0x32c: /* cvttsd2si */
3759          case 0x22d: /* cvtss2si */
3760          case 0x32d: /* cvtsd2si */
3761              ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3762              if (mod != 3) {
3763                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3764                  if ((b >> 8) & 1) {
3765                      gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
3766                  } else {
3767                      gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3768                      tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3769                  }
3770                  op2_offset = offsetof(CPUX86State,xmm_t0);
3771              } else {
3772                  rm = (modrm & 7) | REX_B(s);
3773                  op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3774              }
3775              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3776              if (ot == OT_LONG) {
3777                  SSEFunc_i_ep sse_fn_i_ep =
3778                      sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3779                  sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3780                  tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3781              } else {
3782  #ifdef TARGET_X86_64
3783                  SSEFunc_l_ep sse_fn_l_ep =
3784                      sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3785                  sse_fn_l_ep(cpu_T[0], cpu_env, cpu_ptr0);
3786  #else
3787                  goto illegal_op;
3788  #endif
3789              }
3790              gen_op_mov_reg_T0(ot, reg);
3791              break;
3792          case 0xc4: /* pinsrw */
3793          case 0x1c4:
3794              s->rip_offset = 1;
3795              gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
3796              val = cpu_ldub_code(env, s->pc++);
3797              if (b1) {
3798                  val &= 7;
3799                  tcg_gen_st16_tl(cpu_T[0], cpu_env,
3800                                  offsetof(CPUX86State,xmm_regs[reg].XMM_W(val)));
3801              } else {
3802                  val &= 3;
3803                  tcg_gen_st16_tl(cpu_T[0], cpu_env,
3804                                  offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3805              }
3806              break;
3807          case 0xc5: /* pextrw */
3808          case 0x1c5:
3809              if (mod != 3)
3810                  goto illegal_op;
3811              ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3812              val = cpu_ldub_code(env, s->pc++);
3813              if (b1) {
3814                  val &= 7;
3815                  rm = (modrm & 7) | REX_B(s);
3816                  tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3817                                   offsetof(CPUX86State,xmm_regs[rm].XMM_W(val)));
3818              } else {
3819                  val &= 3;
3820                  rm = (modrm & 7);
3821                  tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3822                                  offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3823              }
3824              reg = ((modrm >> 3) & 7) | rex_r;
3825              gen_op_mov_reg_T0(ot, reg);
3826              break;
3827          case 0x1d6: /* movq ea, xmm */
3828              if (mod != 3) {
3829                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3830                  gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3831              } else {
3832                  rm = (modrm & 7) | REX_B(s);
3833                  gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3834                              offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3835                  gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3836              }
3837              break;
3838          case 0x2d6: /* movq2dq */
3839              gen_helper_enter_mmx(cpu_env);
3840              rm = (modrm & 7);
3841              gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3842                          offsetof(CPUX86State,fpregs[rm].mmx));
3843              gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3844              break;
3845          case 0x3d6: /* movdq2q */
3846              gen_helper_enter_mmx(cpu_env);
3847              rm = (modrm & 7) | REX_B(s);
3848              gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3849                          offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3850              break;
3851          case 0xd7: /* pmovmskb */
3852          case 0x1d7:
3853              if (mod != 3)
3854                  goto illegal_op;
3855              if (b1) {
3856                  rm = (modrm & 7) | REX_B(s);
3857                  tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3858                  gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3859              } else {
3860                  rm = (modrm & 7);
3861                  tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3862                  gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3863              }
3864              tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3865              reg = ((modrm >> 3) & 7) | rex_r;
3866              gen_op_mov_reg_T0(OT_LONG, reg);
3867              break;
3868  
3869          case 0x138:
3870              if (s->prefix & PREFIX_REPNZ)
3871                  goto crc32;
3872          case 0x038:
3873              b = modrm;
3874              modrm = cpu_ldub_code(env, s->pc++);
3875              rm = modrm & 7;
3876              reg = ((modrm >> 3) & 7) | rex_r;
3877              mod = (modrm >> 6) & 3;
3878  
3879              sse_fn_epp = sse_op_table6[b].op[b1];
3880              if (!sse_fn_epp) {
3881                  goto illegal_op;
3882              }
3883              if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3884                  goto illegal_op;
3885  
3886              if (b1) {
3887                  op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3888                  if (mod == 3) {
3889                      op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3890                  } else {
3891                      op2_offset = offsetof(CPUX86State,xmm_t0);
3892                      gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3893                      switch (b) {
3894                      case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3895                      case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3896                      case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3897                          gen_ldq_env_A0(s->mem_index, op2_offset +
3898                                          offsetof(XMMReg, XMM_Q(0)));
3899                          break;
3900                      case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3901                      case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3902                          tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
3903                                            (s->mem_index >> 2) - 1);
3904                          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
3905                          tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3906                                          offsetof(XMMReg, XMM_L(0)));
3907                          break;
3908                      case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3909                          tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0,
3910                                            (s->mem_index >> 2) - 1);
3911                          tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3912                                          offsetof(XMMReg, XMM_W(0)));
3913                          break;
3914                      case 0x2a:            /* movntqda */
3915                          gen_ldo_env_A0(s->mem_index, op1_offset);
3916                          return;
3917                      default:
3918                          gen_ldo_env_A0(s->mem_index, op2_offset);
3919                      }
3920                  }
3921              } else {
3922                  op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3923                  if (mod == 3) {
3924                      op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3925                  } else {
3926                      op2_offset = offsetof(CPUX86State,mmx_t0);
3927                      gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3928                      gen_ldq_env_A0(s->mem_index, op2_offset);
3929                  }
3930              }
3931              if (sse_fn_epp == SSE_SPECIAL) {
3932                  goto illegal_op;
3933              }
3934  
3935              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3936              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3937              sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3938  
3939              if (b == 0x17) {
3940                  set_cc_op(s, CC_OP_EFLAGS);
3941              }
3942              break;
3943          case 0x338: /* crc32 */
3944          crc32:
3945              b = modrm;
3946              modrm = cpu_ldub_code(env, s->pc++);
3947              reg = ((modrm >> 3) & 7) | rex_r;
3948  
3949              if (b != 0xf0 && b != 0xf1)
3950                  goto illegal_op;
3951              if (!(s->cpuid_ext_features & CPUID_EXT_SSE42))
3952                  goto illegal_op;
3953  
3954              if (b == 0xf0)
3955                  ot = OT_BYTE;
3956              else if (b == 0xf1 && s->dflag != 2)
3957                  if (s->prefix & PREFIX_DATA)
3958                      ot = OT_WORD;
3959                  else
3960                      ot = OT_LONG;
3961              else
3962                  ot = OT_QUAD;
3963  
3964              gen_op_mov_TN_reg(OT_LONG, 0, reg);
3965              tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3966              gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3967              gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
3968                               cpu_T[0], tcg_const_i32(8 << ot));
3969  
3970              ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3971              gen_op_mov_reg_T0(ot, reg);
3972              break;
3973  
3974          case 0x03a:
3975          case 0x13a:
3976              b = modrm;
3977              modrm = cpu_ldub_code(env, s->pc++);
3978              rm = modrm & 7;
3979              reg = ((modrm >> 3) & 7) | rex_r;
3980              mod = (modrm >> 6) & 3;
3981  
3982              sse_fn_eppi = sse_op_table7[b].op[b1];
3983              if (!sse_fn_eppi) {
3984                  goto illegal_op;
3985              }
3986              if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
3987                  goto illegal_op;
3988  
3989              if (sse_fn_eppi == SSE_SPECIAL) {
3990                  ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3991                  rm = (modrm & 7) | REX_B(s);
3992                  if (mod != 3)
3993                      gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
3994                  reg = ((modrm >> 3) & 7) | rex_r;
3995                  val = cpu_ldub_code(env, s->pc++);
3996                  switch (b) {
3997                  case 0x14: /* pextrb */
3998                      tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3999                                              xmm_regs[reg].XMM_B(val & 15)));
4000                      if (mod == 3)
4001                          gen_op_mov_reg_T0(ot, rm);
4002                      else
4003                          tcg_gen_qemu_st8(cpu_T[0], cpu_A0,
4004                                          (s->mem_index >> 2) - 1);
4005                      break;
4006                  case 0x15: /* pextrw */
4007                      tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4008                                              xmm_regs[reg].XMM_W(val & 7)));
4009                      if (mod == 3)
4010                          gen_op_mov_reg_T0(ot, rm);
4011                      else
4012                          tcg_gen_qemu_st16(cpu_T[0], cpu_A0,
4013                                          (s->mem_index >> 2) - 1);
4014                      break;
4015                  case 0x16:
4016                      if (ot == OT_LONG) { /* pextrd */
4017                          tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4018                                          offsetof(CPUX86State,
4019                                                  xmm_regs[reg].XMM_L(val & 3)));
4020                          tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
4021                          if (mod == 3)
4022                              gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4023                          else
4024                              tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
4025                                              (s->mem_index >> 2) - 1);
4026                      } else { /* pextrq */
4027  #ifdef TARGET_X86_64
4028                          tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4029                                          offsetof(CPUX86State,
4030                                                  xmm_regs[reg].XMM_Q(val & 1)));
4031                          if (mod == 3)
4032                              gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64);
4033                          else
4034                              tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
4035                                              (s->mem_index >> 2) - 1);
4036  #else
4037                          goto illegal_op;
4038  #endif
4039                      }
4040                      break;
4041                  case 0x17: /* extractps */
4042                      tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4043                                              xmm_regs[reg].XMM_L(val & 3)));
4044                      if (mod == 3)
4045                          gen_op_mov_reg_T0(ot, rm);
4046                      else
4047                          tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
4048                                          (s->mem_index >> 2) - 1);
4049                      break;
4050                  case 0x20: /* pinsrb */
4051                      if (mod == 3)
4052                          gen_op_mov_TN_reg(OT_LONG, 0, rm);
4053                      else
4054                          tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0,
4055                                          (s->mem_index >> 2) - 1);
4056                      tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State,
4057                                              xmm_regs[reg].XMM_B(val & 15)));
4058                      break;
4059                  case 0x21: /* insertps */
4060                      if (mod == 3) {
4061                          tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4062                                          offsetof(CPUX86State,xmm_regs[rm]
4063                                                  .XMM_L((val >> 6) & 3)));
4064                      } else {
4065                          tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
4066                                          (s->mem_index >> 2) - 1);
4067                          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
4068                      }
4069                      tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4070                                      offsetof(CPUX86State,xmm_regs[reg]
4071                                              .XMM_L((val >> 4) & 3)));
4072                      if ((val >> 0) & 1)
4073                          tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4074                                          cpu_env, offsetof(CPUX86State,
4075                                                  xmm_regs[reg].XMM_L(0)));
4076                      if ((val >> 1) & 1)
4077                          tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4078                                          cpu_env, offsetof(CPUX86State,
4079                                                  xmm_regs[reg].XMM_L(1)));
4080                      if ((val >> 2) & 1)
4081                          tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4082                                          cpu_env, offsetof(CPUX86State,
4083                                                  xmm_regs[reg].XMM_L(2)));
4084                      if ((val >> 3) & 1)
4085                          tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4086                                          cpu_env, offsetof(CPUX86State,
4087                                                  xmm_regs[reg].XMM_L(3)));
4088                      break;
4089                  case 0x22:
4090                      if (ot == OT_LONG) { /* pinsrd */
4091                          if (mod == 3)
4092                              gen_op_mov_v_reg(ot, cpu_tmp0, rm);
4093                          else
4094                              tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
4095                                              (s->mem_index >> 2) - 1);
4096                          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
4097                          tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4098                                          offsetof(CPUX86State,
4099                                                  xmm_regs[reg].XMM_L(val & 3)));
4100                      } else { /* pinsrq */
4101  #ifdef TARGET_X86_64
4102                          if (mod == 3)
4103                              gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4104                          else
4105                              tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
4106                                              (s->mem_index >> 2) - 1);
4107                          tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4108                                          offsetof(CPUX86State,
4109                                                  xmm_regs[reg].XMM_Q(val & 1)));
4110  #else
4111                          goto illegal_op;
4112  #endif
4113                      }
4114                      break;
4115                  }
4116                  return;
4117              }
4118  
4119              if (b1) {
4120                  op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4121                  if (mod == 3) {
4122                      op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4123                  } else {
4124                      op2_offset = offsetof(CPUX86State,xmm_t0);
4125                      gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4126                      gen_ldo_env_A0(s->mem_index, op2_offset);
4127                  }
4128              } else {
4129                  op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4130                  if (mod == 3) {
4131                      op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4132                  } else {
4133                      op2_offset = offsetof(CPUX86State,mmx_t0);
4134                      gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4135                      gen_ldq_env_A0(s->mem_index, op2_offset);
4136                  }
4137              }
4138              val = cpu_ldub_code(env, s->pc++);
4139  
4140              if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4141                  set_cc_op(s, CC_OP_EFLAGS);
4142  
4143                  if (s->dflag == 2)
4144                      /* The helper must use entire 64-bit gp registers */
4145                      val |= 1 << 8;
4146              }
4147  
4148              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4149              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4150              sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4151              break;
4152          default:
4153              goto illegal_op;
4154          }
4155      } else {
4156          /* generic MMX or SSE operation */
4157          switch(b) {
4158          case 0x70: /* pshufx insn */
4159          case 0xc6: /* pshufx insn */
4160          case 0xc2: /* compare insns */
4161              s->rip_offset = 1;
4162              break;
4163          default:
4164              break;
4165          }
4166          if (is_xmm) {
4167              op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4168              if (mod != 3) {
4169                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4170                  op2_offset = offsetof(CPUX86State,xmm_t0);
4171                  if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
4172                                  b == 0xc2)) {
4173                      /* specific case for SSE single instructions */
4174                      if (b1 == 2) {
4175                          /* 32 bit access */
4176                          gen_op_ld_T0_A0(OT_LONG + s->mem_index);
4177                          tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
4178                      } else {
4179                          /* 64 bit access */
4180                          gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
4181                      }
4182                  } else {
4183                      gen_ldo_env_A0(s->mem_index, op2_offset);
4184                  }
4185              } else {
4186                  rm = (modrm & 7) | REX_B(s);
4187                  op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4188              }
4189          } else {
4190              op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4191              if (mod != 3) {
4192                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4193                  op2_offset = offsetof(CPUX86State,mmx_t0);
4194                  gen_ldq_env_A0(s->mem_index, op2_offset);
4195              } else {
4196                  rm = (modrm & 7);
4197                  op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4198              }
4199          }
4200          switch(b) {
4201          case 0x0f: /* 3DNow! data insns */
4202              if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
4203                  goto illegal_op;
4204              val = cpu_ldub_code(env, s->pc++);
4205              sse_fn_epp = sse_op_table5[val];
4206              if (!sse_fn_epp) {
4207                  goto illegal_op;
4208              }
4209              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4210              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4211              sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4212              break;
4213          case 0x70: /* pshufx insn */
4214          case 0xc6: /* pshufx insn */
4215              val = cpu_ldub_code(env, s->pc++);
4216              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4217              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4218              /* XXX: introduce a new table? */
4219              sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4220              sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4221              break;
4222          case 0xc2:
4223              /* compare insns */
4224              val = cpu_ldub_code(env, s->pc++);
4225              if (val >= 8)
4226                  goto illegal_op;
4227              sse_fn_epp = sse_op_table4[val][b1];
4228  
4229              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4230              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4231              sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4232              break;
4233          case 0xf7:
4234              /* maskmov : we must prepare A0 */
4235              if (mod != 3)
4236                  goto illegal_op;
4237  #ifdef TARGET_X86_64
4238              if (s->aflag == 2) {
4239                  gen_op_movq_A0_reg(R_EDI);
4240              } else
4241  #endif
4242              {
4243                  gen_op_movl_A0_reg(R_EDI);
4244                  if (s->aflag == 0)
4245                      gen_op_andl_A0_ffff();
4246              }
4247              gen_add_A0_ds_seg(s);
4248  
4249              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4250              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4251              /* XXX: introduce a new table? */
4252              sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4253              sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4254              break;
4255          default:
4256              tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4257              tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4258              sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4259              break;
4260          }
4261          if (b == 0x2e || b == 0x2f) {
4262              set_cc_op(s, CC_OP_EFLAGS);
4263          }
4264      }
4265  }
4266  
4267  /* convert one instruction. s->is_jmp is set if the translation must
4268     be stopped. Return the next pc value */
disas_insn(CPUX86State * env,DisasContext * s,target_ulong pc_start)4269  static target_ulong disas_insn(CPUX86State *env, DisasContext *s, target_ulong pc_start)
4270  {
4271      int b, prefixes, aflag, dflag;
4272      int shift, ot;
4273      int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
4274      target_ulong next_eip, tval;
4275  #ifdef TARGET_X86_64
4276      int rex_w = -1;
4277  #endif
4278      int rex_r;
4279  
4280      if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
4281          tcg_gen_debug_insn_start(pc_start);
4282      }
4283      s->pc = pc_start;
4284      prefixes = 0;
4285      aflag = s->code32;
4286      dflag = s->code32;
4287      s->override = -1;
4288      rex_r = 0;
4289  #ifdef TARGET_X86_64
4290      s->rex_x = 0;
4291      s->rex_b = 0;
4292      x86_64_hregs = 0;
4293  #endif
4294      s->rip_offset = 0; /* for relative ip address */
4295   next_byte:
4296      b = cpu_ldub_code(env, s->pc);
4297      s->pc++;
4298      /* check prefixes */
4299  #ifdef TARGET_X86_64
4300      if (CODE64(s)) {
4301          switch (b) {
4302          case 0xf3:
4303              prefixes |= PREFIX_REPZ;
4304              goto next_byte;
4305          case 0xf2:
4306              prefixes |= PREFIX_REPNZ;
4307              goto next_byte;
4308          case 0xf0:
4309              prefixes |= PREFIX_LOCK;
4310              goto next_byte;
4311          case 0x2e:
4312              s->override = R_CS;
4313              goto next_byte;
4314          case 0x36:
4315              s->override = R_SS;
4316              goto next_byte;
4317          case 0x3e:
4318              s->override = R_DS;
4319              goto next_byte;
4320          case 0x26:
4321              s->override = R_ES;
4322              goto next_byte;
4323          case 0x64:
4324              s->override = R_FS;
4325              goto next_byte;
4326          case 0x65:
4327              s->override = R_GS;
4328              goto next_byte;
4329          case 0x66:
4330              prefixes |= PREFIX_DATA;
4331              goto next_byte;
4332          case 0x67:
4333              prefixes |= PREFIX_ADR;
4334              goto next_byte;
4335          case 0x40 ... 0x4f:
4336              /* REX prefix */
4337              rex_w = (b >> 3) & 1;
4338              rex_r = (b & 0x4) << 1;
4339              s->rex_x = (b & 0x2) << 2;
4340              REX_B(s) = (b & 0x1) << 3;
4341              x86_64_hregs = 1; /* select uniform byte register addressing */
4342              goto next_byte;
4343          }
4344          if (rex_w == 1) {
4345              /* 0x66 is ignored if rex.w is set */
4346              dflag = 2;
4347          } else {
4348              if (prefixes & PREFIX_DATA)
4349                  dflag ^= 1;
4350          }
4351          if (!(prefixes & PREFIX_ADR))
4352              aflag = 2;
4353      } else
4354  #endif
4355      {
4356          switch (b) {
4357          case 0xf3:
4358              prefixes |= PREFIX_REPZ;
4359              goto next_byte;
4360          case 0xf2:
4361              prefixes |= PREFIX_REPNZ;
4362              goto next_byte;
4363          case 0xf0:
4364              prefixes |= PREFIX_LOCK;
4365              goto next_byte;
4366          case 0x2e:
4367              s->override = R_CS;
4368              goto next_byte;
4369          case 0x36:
4370              s->override = R_SS;
4371              goto next_byte;
4372          case 0x3e:
4373              s->override = R_DS;
4374              goto next_byte;
4375          case 0x26:
4376              s->override = R_ES;
4377              goto next_byte;
4378          case 0x64:
4379              s->override = R_FS;
4380              goto next_byte;
4381          case 0x65:
4382              s->override = R_GS;
4383              goto next_byte;
4384          case 0x66:
4385              prefixes |= PREFIX_DATA;
4386              goto next_byte;
4387          case 0x67:
4388              prefixes |= PREFIX_ADR;
4389              goto next_byte;
4390          }
4391          if (prefixes & PREFIX_DATA) {
4392              dflag ^= 1;
4393          }
4394          if (prefixes & PREFIX_ADR) {
4395              aflag ^= 1;
4396          }
4397      }
4398  
4399      s->prefix = prefixes;
4400      s->aflag = aflag;
4401      s->dflag = dflag;
4402  
4403      /* lock generation */
4404      if (prefixes & PREFIX_LOCK)
4405          gen_helper_lock();
4406  
4407      /* now check op code */
4408   reswitch:
4409      switch(b) {
4410      case 0x0f:
4411          /**************************/
4412          /* extended op code */
4413          b = cpu_ldub_code(env, s->pc++) | 0x100;
4414          goto reswitch;
4415  
4416          /**************************/
4417          /* arith & logic */
4418      case 0x00 ... 0x05:
4419      case 0x08 ... 0x0d:
4420      case 0x10 ... 0x15:
4421      case 0x18 ... 0x1d:
4422      case 0x20 ... 0x25:
4423      case 0x28 ... 0x2d:
4424      case 0x30 ... 0x35:
4425      case 0x38 ... 0x3d:
4426          {
4427              int op, f, val;
4428              op = (b >> 3) & 7;
4429              f = (b >> 1) & 3;
4430  
4431              if ((b & 1) == 0)
4432                  ot = OT_BYTE;
4433              else
4434                  ot = dflag + OT_WORD;
4435  
4436              switch(f) {
4437              case 0: /* OP Ev, Gv */
4438                  modrm = cpu_ldub_code(env, s->pc++);
4439                  reg = ((modrm >> 3) & 7) | rex_r;
4440                  mod = (modrm >> 6) & 3;
4441                  rm = (modrm & 7) | REX_B(s);
4442                  if (mod != 3) {
4443                      gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4444                      opreg = OR_TMP0;
4445                  } else if (op == OP_XORL && rm == reg) {
4446                  xor_zero:
4447                      /* xor reg, reg optimisation */
4448                      gen_op_movl_T0_0();
4449                      set_cc_op(s, CC_OP_LOGICB + ot);
4450                      gen_op_mov_reg_T0(ot, reg);
4451                      gen_op_update1_cc();
4452                      break;
4453                  } else {
4454                      opreg = rm;
4455                  }
4456                  gen_op_mov_TN_reg(ot, 1, reg);
4457                  gen_op(s, op, ot, opreg);
4458                  break;
4459              case 1: /* OP Gv, Ev */
4460                  modrm = cpu_ldub_code(env, s->pc++);
4461                  mod = (modrm >> 6) & 3;
4462                  reg = ((modrm >> 3) & 7) | rex_r;
4463                  rm = (modrm & 7) | REX_B(s);
4464                  if (mod != 3) {
4465                      gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4466                      gen_op_ld_T1_A0(ot + s->mem_index);
4467                  } else if (op == OP_XORL && rm == reg) {
4468                      goto xor_zero;
4469                  } else {
4470                      gen_op_mov_TN_reg(ot, 1, rm);
4471                  }
4472                  gen_op(s, op, ot, reg);
4473                  break;
4474              case 2: /* OP A, Iv */
4475                  val = insn_get(env, s, ot);
4476                  gen_op_movl_T1_im(val);
4477                  gen_op(s, op, ot, OR_EAX);
4478                  break;
4479              }
4480          }
4481          break;
4482  
4483      case 0x82:
4484          if (CODE64(s))
4485              goto illegal_op;
4486      case 0x80: /* GRP1 */
4487      case 0x81:
4488      case 0x83:
4489          {
4490              int val;
4491  
4492              if ((b & 1) == 0)
4493                  ot = OT_BYTE;
4494              else
4495                  ot = dflag + OT_WORD;
4496  
4497              modrm = cpu_ldub_code(env, s->pc++);
4498              mod = (modrm >> 6) & 3;
4499              rm = (modrm & 7) | REX_B(s);
4500              op = (modrm >> 3) & 7;
4501  
4502              if (mod != 3) {
4503                  if (b == 0x83)
4504                      s->rip_offset = 1;
4505                  else
4506                      s->rip_offset = insn_const_size(ot);
4507                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4508                  opreg = OR_TMP0;
4509              } else {
4510                  opreg = rm;
4511              }
4512  
4513              switch(b) {
4514              default:
4515              case 0x80:
4516              case 0x81:
4517              case 0x82:
4518                  val = insn_get(env, s, ot);
4519                  break;
4520              case 0x83:
4521                  val = (int8_t)insn_get(env, s, OT_BYTE);
4522                  break;
4523              }
4524              gen_op_movl_T1_im(val);
4525              gen_op(s, op, ot, opreg);
4526          }
4527          break;
4528  
4529          /**************************/
4530          /* inc, dec, and other misc arith */
4531      case 0x40 ... 0x47: /* inc Gv */
4532          ot = dflag ? OT_LONG : OT_WORD;
4533          gen_inc(s, ot, OR_EAX + (b & 7), 1);
4534          break;
4535      case 0x48 ... 0x4f: /* dec Gv */
4536          ot = dflag ? OT_LONG : OT_WORD;
4537          gen_inc(s, ot, OR_EAX + (b & 7), -1);
4538          break;
4539      case 0xf6: /* GRP3 */
4540      case 0xf7:
4541          if ((b & 1) == 0)
4542              ot = OT_BYTE;
4543          else
4544              ot = dflag + OT_WORD;
4545  
4546          modrm = cpu_ldub_code(env, s->pc++);
4547          mod = (modrm >> 6) & 3;
4548          rm = (modrm & 7) | REX_B(s);
4549          op = (modrm >> 3) & 7;
4550          if (mod != 3) {
4551              if (op == 0)
4552                  s->rip_offset = insn_const_size(ot);
4553              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4554              gen_op_ld_T0_A0(ot + s->mem_index);
4555          } else {
4556              gen_op_mov_TN_reg(ot, 0, rm);
4557          }
4558  
4559          switch(op) {
4560          case 0: /* test */
4561              val = insn_get(env, s, ot);
4562              gen_op_movl_T1_im(val);
4563              gen_op_testl_T0_T1_cc();
4564              set_cc_op(s, CC_OP_LOGICB + ot);
4565              break;
4566          case 2: /* not */
4567              tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
4568              if (mod != 3) {
4569                  gen_op_st_T0_A0(ot + s->mem_index);
4570              } else {
4571                  gen_op_mov_reg_T0(ot, rm);
4572              }
4573              break;
4574          case 3: /* neg */
4575              tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
4576              if (mod != 3) {
4577                  gen_op_st_T0_A0(ot + s->mem_index);
4578              } else {
4579                  gen_op_mov_reg_T0(ot, rm);
4580              }
4581              gen_op_update_neg_cc();
4582              set_cc_op(s, CC_OP_SUBB + ot);
4583              break;
4584          case 4: /* mul */
4585              switch(ot) {
4586              case OT_BYTE:
4587                  gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4588                  tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4589                  tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
4590                  /* XXX: use 32 bit mul which could be faster */
4591                  tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4592                  gen_op_mov_reg_T0(OT_WORD, R_EAX);
4593                  tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4594                  tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
4595                  set_cc_op(s, CC_OP_MULB);
4596                  break;
4597              case OT_WORD:
4598                  gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4599                  tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4600                  tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
4601                  /* XXX: use 32 bit mul which could be faster */
4602                  tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4603                  gen_op_mov_reg_T0(OT_WORD, R_EAX);
4604                  tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4605                  tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4606                  gen_op_mov_reg_T0(OT_WORD, R_EDX);
4607                  tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4608                  set_cc_op(s, CC_OP_MULW);
4609                  break;
4610              default:
4611              case OT_LONG:
4612  #ifdef TARGET_X86_64
4613                  gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4614                  tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
4615                  tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
4616                  tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4617                  gen_op_mov_reg_T0(OT_LONG, R_EAX);
4618                  tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4619                  tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4620                  gen_op_mov_reg_T0(OT_LONG, R_EDX);
4621                  tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4622  #else
4623                  {
4624                      TCGv_i64 t0, t1;
4625                      t0 = tcg_temp_new_i64();
4626                      t1 = tcg_temp_new_i64();
4627                      gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4628                      tcg_gen_extu_i32_i64(t0, cpu_T[0]);
4629                      tcg_gen_extu_i32_i64(t1, cpu_T[1]);
4630                      tcg_gen_mul_i64(t0, t0, t1);
4631                      tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4632                      gen_op_mov_reg_T0(OT_LONG, R_EAX);
4633                      tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4634                      tcg_gen_shri_i64(t0, t0, 32);
4635                      tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4636                      gen_op_mov_reg_T0(OT_LONG, R_EDX);
4637                      tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4638                  }
4639  #endif
4640                  set_cc_op(s, CC_OP_MULL);
4641                  break;
4642  #ifdef TARGET_X86_64
4643              case OT_QUAD:
4644                  gen_helper_mulq_EAX_T0(cpu_env, cpu_T[0]);
4645                  set_cc_op(s, CC_OP_MULQ);
4646                  break;
4647  #endif
4648              }
4649              break;
4650          case 5: /* imul */
4651              switch(ot) {
4652              case OT_BYTE:
4653                  gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
4654                  tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4655                  tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
4656                  /* XXX: use 32 bit mul which could be faster */
4657                  tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4658                  gen_op_mov_reg_T0(OT_WORD, R_EAX);
4659                  tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4660                  tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
4661                  tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4662                  set_cc_op(s, CC_OP_MULB);
4663                  break;
4664              case OT_WORD:
4665                  gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
4666                  tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4667                  tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4668                  /* XXX: use 32 bit mul which could be faster */
4669                  tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4670                  gen_op_mov_reg_T0(OT_WORD, R_EAX);
4671                  tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4672                  tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4673                  tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4674                  tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4675                  gen_op_mov_reg_T0(OT_WORD, R_EDX);
4676                  set_cc_op(s, CC_OP_MULW);
4677                  break;
4678              default:
4679              case OT_LONG:
4680  #ifdef TARGET_X86_64
4681                  gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4682                  tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4683                  tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4684                  tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4685                  gen_op_mov_reg_T0(OT_LONG, R_EAX);
4686                  tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4687                  tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4688                  tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4689                  tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
4690                  gen_op_mov_reg_T0(OT_LONG, R_EDX);
4691  #else
4692                  {
4693                      TCGv_i64 t0, t1;
4694                      t0 = tcg_temp_new_i64();
4695                      t1 = tcg_temp_new_i64();
4696                      gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
4697                      tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4698                      tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4699                      tcg_gen_mul_i64(t0, t0, t1);
4700                      tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4701                      gen_op_mov_reg_T0(OT_LONG, R_EAX);
4702                      tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4703                      tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4704                      tcg_gen_shri_i64(t0, t0, 32);
4705                      tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4706                      gen_op_mov_reg_T0(OT_LONG, R_EDX);
4707                      tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4708                  }
4709  #endif
4710                  set_cc_op(s, CC_OP_MULL);
4711                  break;
4712  #ifdef TARGET_X86_64
4713              case OT_QUAD:
4714                  gen_helper_imulq_EAX_T0(cpu_env, cpu_T[0]);
4715                  set_cc_op(s, CC_OP_MULQ);
4716                  break;
4717  #endif
4718              }
4719              break;
4720          case 6: /* div */
4721              switch(ot) {
4722              case OT_BYTE:
4723                  gen_jmp_im(pc_start - s->cs_base);
4724                  gen_helper_divb_AL(cpu_env, cpu_T[0]);
4725                  break;
4726              case OT_WORD:
4727                  gen_jmp_im(pc_start - s->cs_base);
4728                  gen_helper_divw_AX(cpu_env, cpu_T[0]);
4729                  break;
4730              default:
4731              case OT_LONG:
4732                  gen_jmp_im(pc_start - s->cs_base);
4733                  gen_helper_divl_EAX(cpu_env, cpu_T[0]);
4734                  break;
4735  #ifdef TARGET_X86_64
4736              case OT_QUAD:
4737                  gen_jmp_im(pc_start - s->cs_base);
4738                  gen_helper_divq_EAX(cpu_env, cpu_T[0]);
4739                  break;
4740  #endif
4741              }
4742              break;
4743          case 7: /* idiv */
4744              switch(ot) {
4745              case OT_BYTE:
4746                  gen_jmp_im(pc_start - s->cs_base);
4747                  gen_helper_idivb_AL(cpu_env, cpu_T[0]);
4748                  break;
4749              case OT_WORD:
4750                  gen_jmp_im(pc_start - s->cs_base);
4751                  gen_helper_idivw_AX(cpu_env, cpu_T[0]);
4752                  break;
4753              default:
4754              case OT_LONG:
4755                  gen_jmp_im(pc_start - s->cs_base);
4756                  gen_helper_idivl_EAX(cpu_env, cpu_T[0]);
4757                  break;
4758  #ifdef TARGET_X86_64
4759              case OT_QUAD:
4760                  gen_jmp_im(pc_start - s->cs_base);
4761                  gen_helper_idivq_EAX(cpu_env, cpu_T[0]);
4762                  break;
4763  #endif
4764              }
4765              break;
4766          default:
4767              goto illegal_op;
4768          }
4769          break;
4770  
4771      case 0xfe: /* GRP4 */
4772      case 0xff: /* GRP5 */
4773          if ((b & 1) == 0)
4774              ot = OT_BYTE;
4775          else
4776              ot = dflag + OT_WORD;
4777  
4778          modrm = cpu_ldub_code(env, s->pc++);
4779          mod = (modrm >> 6) & 3;
4780          rm = (modrm & 7) | REX_B(s);
4781          op = (modrm >> 3) & 7;
4782          if (op >= 2 && b == 0xfe) {
4783              goto illegal_op;
4784          }
4785          if (CODE64(s)) {
4786              if (op == 2 || op == 4) {
4787                  /* operand size for jumps is 64 bit */
4788                  ot = OT_QUAD;
4789              } else if (op == 3 || op == 5) {
4790                  /* for call calls, the operand is 16 or 32 bit, even
4791                     in long mode */
4792                  ot = dflag ? OT_LONG : OT_WORD;
4793              } else if (op == 6) {
4794                  /* default push size is 64 bit */
4795                  ot = dflag ? OT_QUAD : OT_WORD;
4796              }
4797          }
4798          if (mod != 3) {
4799              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
4800              if (op >= 2 && op != 3 && op != 5)
4801                  gen_op_ld_T0_A0(ot + s->mem_index);
4802          } else {
4803              gen_op_mov_TN_reg(ot, 0, rm);
4804          }
4805  
4806          switch(op) {
4807          case 0: /* inc Ev */
4808              if (mod != 3)
4809                  opreg = OR_TMP0;
4810              else
4811                  opreg = rm;
4812              gen_inc(s, ot, opreg, 1);
4813              break;
4814          case 1: /* dec Ev */
4815              if (mod != 3)
4816                  opreg = OR_TMP0;
4817              else
4818                  opreg = rm;
4819              gen_inc(s, ot, opreg, -1);
4820              break;
4821          case 2: /* call Ev */
4822              /* XXX: optimize if memory (no 'and' is necessary) */
4823              if (s->dflag == 0)
4824                  gen_op_andl_T0_ffff();
4825              next_eip = s->pc - s->cs_base;
4826              gen_movtl_T1_im(next_eip);
4827              gen_push_T1(s);
4828              gen_op_jmp_T0();
4829              gen_eob(s);
4830              break;
4831          case 3: /* lcall Ev */
4832              gen_op_ld_T1_A0(ot + s->mem_index);
4833              gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4834              gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4835          do_lcall:
4836              if (s->pe && !s->vm86) {
4837                  gen_update_cc_op(s);
4838                  gen_jmp_im(pc_start - s->cs_base);
4839                  tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4840                  gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
4841                                             tcg_const_i32(dflag),
4842                                             tcg_const_i32(s->pc - pc_start));
4843              } else {
4844                  tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4845                  gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T[1],
4846                                        tcg_const_i32(dflag),
4847                                        tcg_const_i32(s->pc - s->cs_base));
4848              }
4849              gen_eob(s);
4850              break;
4851          case 4: /* jmp Ev */
4852              if (s->dflag == 0)
4853                  gen_op_andl_T0_ffff();
4854              gen_op_jmp_T0();
4855              gen_eob(s);
4856              break;
4857          case 5: /* ljmp Ev */
4858              gen_op_ld_T1_A0(ot + s->mem_index);
4859              gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4860              gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4861          do_ljmp:
4862              if (s->pe && !s->vm86) {
4863                  gen_update_cc_op(s);
4864                  gen_jmp_im(pc_start - s->cs_base);
4865                  tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4866                  gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
4867                                            tcg_const_i32(s->pc - pc_start));
4868              } else {
4869                  gen_op_movl_seg_T0_vm(R_CS);
4870                  gen_op_movl_T0_T1();
4871                  gen_op_jmp_T0();
4872              }
4873              gen_eob(s);
4874              break;
4875          case 6: /* push Ev */
4876              gen_push_T0(s);
4877              break;
4878          default:
4879              goto illegal_op;
4880          }
4881          break;
4882  
4883      case 0x84: /* test Ev, Gv */
4884      case 0x85:
4885          if ((b & 1) == 0)
4886              ot = OT_BYTE;
4887          else
4888              ot = dflag + OT_WORD;
4889  
4890          modrm = cpu_ldub_code(env, s->pc++);
4891          mod = (modrm >> 6) & 3;
4892          rm = (modrm & 7) | REX_B(s);
4893          reg = ((modrm >> 3) & 7) | rex_r;
4894  
4895          gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4896          gen_op_mov_TN_reg(ot, 1, reg);
4897          gen_op_testl_T0_T1_cc();
4898          set_cc_op(s, CC_OP_LOGICB + ot);
4899          break;
4900  
4901      case 0xa8: /* test eAX, Iv */
4902      case 0xa9:
4903          if ((b & 1) == 0)
4904              ot = OT_BYTE;
4905          else
4906              ot = dflag + OT_WORD;
4907          val = insn_get(env, s, ot);
4908  
4909          gen_op_mov_TN_reg(ot, 0, OR_EAX);
4910          gen_op_movl_T1_im(val);
4911          gen_op_testl_T0_T1_cc();
4912          set_cc_op(s, CC_OP_LOGICB + ot);
4913          break;
4914  
4915      case 0x98: /* CWDE/CBW */
4916  #ifdef TARGET_X86_64
4917          if (dflag == 2) {
4918              gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4919              tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4920              gen_op_mov_reg_T0(OT_QUAD, R_EAX);
4921          } else
4922  #endif
4923          if (dflag == 1) {
4924              gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4925              tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4926              gen_op_mov_reg_T0(OT_LONG, R_EAX);
4927          } else {
4928              gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
4929              tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4930              gen_op_mov_reg_T0(OT_WORD, R_EAX);
4931          }
4932          break;
4933      case 0x99: /* CDQ/CWD */
4934  #ifdef TARGET_X86_64
4935          if (dflag == 2) {
4936              gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4937              tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
4938              gen_op_mov_reg_T0(OT_QUAD, R_EDX);
4939          } else
4940  #endif
4941          if (dflag == 1) {
4942              gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4943              tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4944              tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
4945              gen_op_mov_reg_T0(OT_LONG, R_EDX);
4946          } else {
4947              gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
4948              tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4949              tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
4950              gen_op_mov_reg_T0(OT_WORD, R_EDX);
4951          }
4952          break;
4953      case 0x1af: /* imul Gv, Ev */
4954      case 0x69: /* imul Gv, Ev, I */
4955      case 0x6b:
4956          ot = dflag + OT_WORD;
4957          modrm = cpu_ldub_code(env, s->pc++);
4958          reg = ((modrm >> 3) & 7) | rex_r;
4959          if (b == 0x69)
4960              s->rip_offset = insn_const_size(ot);
4961          else if (b == 0x6b)
4962              s->rip_offset = 1;
4963          gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4964          if (b == 0x69) {
4965              val = insn_get(env, s, ot);
4966              gen_op_movl_T1_im(val);
4967          } else if (b == 0x6b) {
4968              val = (int8_t)insn_get(env, s, OT_BYTE);
4969              gen_op_movl_T1_im(val);
4970          } else {
4971              gen_op_mov_TN_reg(ot, 1, reg);
4972          }
4973  
4974  #ifdef TARGET_X86_64
4975          if (ot == OT_QUAD) {
4976              gen_helper_imulq_T0_T1(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
4977          } else
4978  #endif
4979          if (ot == OT_LONG) {
4980  #ifdef TARGET_X86_64
4981                  tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4982                  tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
4983                  tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4984                  tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4985                  tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
4986                  tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4987  #else
4988                  {
4989                      TCGv_i64 t0, t1;
4990                      t0 = tcg_temp_new_i64();
4991                      t1 = tcg_temp_new_i64();
4992                      tcg_gen_ext_i32_i64(t0, cpu_T[0]);
4993                      tcg_gen_ext_i32_i64(t1, cpu_T[1]);
4994                      tcg_gen_mul_i64(t0, t0, t1);
4995                      tcg_gen_trunc_i64_i32(cpu_T[0], t0);
4996                      tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4997                      tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
4998                      tcg_gen_shri_i64(t0, t0, 32);
4999                      tcg_gen_trunc_i64_i32(cpu_T[1], t0);
5000                      tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
5001                  }
5002  #endif
5003          } else {
5004              tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5005              tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
5006              /* XXX: use 32 bit mul which could be faster */
5007              tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5008              tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5009              tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
5010              tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
5011          }
5012          gen_op_mov_reg_T0(ot, reg);
5013          set_cc_op(s, CC_OP_MULB + ot);
5014          break;
5015      case 0x1c0:
5016      case 0x1c1: /* xadd Ev, Gv */
5017          if ((b & 1) == 0)
5018              ot = OT_BYTE;
5019          else
5020              ot = dflag + OT_WORD;
5021          modrm = cpu_ldub_code(env, s->pc++);
5022          reg = ((modrm >> 3) & 7) | rex_r;
5023          mod = (modrm >> 6) & 3;
5024          if (mod == 3) {
5025              rm = (modrm & 7) | REX_B(s);
5026              gen_op_mov_TN_reg(ot, 0, reg);
5027              gen_op_mov_TN_reg(ot, 1, rm);
5028              gen_op_addl_T0_T1();
5029              gen_op_mov_reg_T1(ot, reg);
5030              gen_op_mov_reg_T0(ot, rm);
5031          } else {
5032              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5033              gen_op_mov_TN_reg(ot, 0, reg);
5034              gen_op_ld_T1_A0(ot + s->mem_index);
5035              gen_op_addl_T0_T1();
5036              gen_op_st_T0_A0(ot + s->mem_index);
5037              gen_op_mov_reg_T1(ot, reg);
5038          }
5039          gen_op_update2_cc();
5040          set_cc_op(s, CC_OP_ADDB + ot);
5041          break;
5042      case 0x1b0:
5043      case 0x1b1: /* cmpxchg Ev, Gv */
5044          {
5045              int label1, label2;
5046              TCGv t0, t1, t2, a0;
5047  
5048              if ((b & 1) == 0)
5049                  ot = OT_BYTE;
5050              else
5051                  ot = dflag + OT_WORD;
5052              modrm = cpu_ldub_code(env, s->pc++);
5053              reg = ((modrm >> 3) & 7) | rex_r;
5054              mod = (modrm >> 6) & 3;
5055              t0 = tcg_temp_local_new();
5056              t1 = tcg_temp_local_new();
5057              t2 = tcg_temp_local_new();
5058              a0 = tcg_temp_local_new();
5059              gen_op_mov_v_reg(ot, t1, reg);
5060              if (mod == 3) {
5061                  rm = (modrm & 7) | REX_B(s);
5062                  gen_op_mov_v_reg(ot, t0, rm);
5063              } else {
5064                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5065                  tcg_gen_mov_tl(a0, cpu_A0);
5066                  gen_op_ld_v(ot + s->mem_index, t0, a0);
5067                  rm = 0; /* avoid warning */
5068              }
5069              label1 = gen_new_label();
5070              tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUX86State, regs[R_EAX]));
5071              tcg_gen_sub_tl(t2, t2, t0);
5072              gen_extu(ot, t2);
5073              tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
5074              if (mod == 3) {
5075                  label2 = gen_new_label();
5076                  gen_op_mov_reg_v(ot, R_EAX, t0);
5077                  tcg_gen_br(label2);
5078                  gen_set_label(label1);
5079                  gen_op_mov_reg_v(ot, rm, t1);
5080                  gen_set_label(label2);
5081              } else {
5082                  tcg_gen_mov_tl(t1, t0);
5083                  gen_op_mov_reg_v(ot, R_EAX, t0);
5084                  gen_set_label(label1);
5085                  /* always store */
5086                  gen_op_st_v(ot + s->mem_index, t1, a0);
5087              }
5088              tcg_gen_mov_tl(cpu_cc_src, t0);
5089              tcg_gen_mov_tl(cpu_cc_dst, t2);
5090              set_cc_op(s, CC_OP_SUBB + ot);
5091              tcg_temp_free(t0);
5092              tcg_temp_free(t1);
5093              tcg_temp_free(t2);
5094              tcg_temp_free(a0);
5095          }
5096          break;
5097      case 0x1c7: /* cmpxchg8b */
5098          modrm = cpu_ldub_code(env, s->pc++);
5099          mod = (modrm >> 6) & 3;
5100          if ((mod == 3) || ((modrm & 0x38) != 0x8))
5101              goto illegal_op;
5102  #ifdef TARGET_X86_64
5103          if (dflag == 2) {
5104              if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5105                  goto illegal_op;
5106              gen_jmp_im(pc_start - s->cs_base);
5107              gen_update_cc_op(s);
5108              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5109              gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5110          } else
5111  #endif
5112          {
5113              if (!(s->cpuid_features & CPUID_CX8))
5114                  goto illegal_op;
5115              gen_jmp_im(pc_start - s->cs_base);
5116              gen_update_cc_op(s);
5117              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5118              gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5119          }
5120          set_cc_op(s, CC_OP_EFLAGS);
5121          break;
5122  
5123          /**************************/
5124          /* push/pop */
5125      case 0x50 ... 0x57: /* push */
5126          gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
5127          gen_push_T0(s);
5128          break;
5129      case 0x58 ... 0x5f: /* pop */
5130          if (CODE64(s)) {
5131              ot = dflag ? OT_QUAD : OT_WORD;
5132          } else {
5133              ot = dflag + OT_WORD;
5134          }
5135          gen_pop_T0(s);
5136          /* NOTE: order is important for pop %sp */
5137          gen_pop_update(s);
5138          gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
5139          break;
5140      case 0x60: /* pusha */
5141          if (CODE64(s))
5142              goto illegal_op;
5143          gen_pusha(s);
5144          break;
5145      case 0x61: /* popa */
5146          if (CODE64(s))
5147              goto illegal_op;
5148          gen_popa(s);
5149          break;
5150      case 0x68: /* push Iv */
5151      case 0x6a:
5152          if (CODE64(s)) {
5153              ot = dflag ? OT_QUAD : OT_WORD;
5154          } else {
5155              ot = dflag + OT_WORD;
5156          }
5157          if (b == 0x68)
5158              val = insn_get(env, s, ot);
5159          else
5160              val = (int8_t)insn_get(env, s, OT_BYTE);
5161          gen_op_movl_T0_im(val);
5162          gen_push_T0(s);
5163          break;
5164      case 0x8f: /* pop Ev */
5165          if (CODE64(s)) {
5166              ot = dflag ? OT_QUAD : OT_WORD;
5167          } else {
5168              ot = dflag + OT_WORD;
5169          }
5170          modrm = cpu_ldub_code(env, s->pc++);
5171          mod = (modrm >> 6) & 3;
5172          gen_pop_T0(s);
5173          if (mod == 3) {
5174              /* NOTE: order is important for pop %sp */
5175              gen_pop_update(s);
5176              rm = (modrm & 7) | REX_B(s);
5177              gen_op_mov_reg_T0(ot, rm);
5178          } else {
5179              /* NOTE: order is important too for MMU exceptions */
5180              s->popl_esp_hack = 1 << ot;
5181              gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5182              s->popl_esp_hack = 0;
5183              gen_pop_update(s);
5184          }
5185          break;
5186      case 0xc8: /* enter */
5187          {
5188              int level;
5189              val = cpu_lduw_code(env, s->pc);
5190              s->pc += 2;
5191              level = cpu_ldub_code(env, s->pc++);
5192              gen_enter(s, val, level);
5193          }
5194          break;
5195      case 0xc9: /* leave */
5196          /* XXX: exception not precise (ESP is updated before potential exception) */
5197          if (CODE64(s)) {
5198              gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
5199              gen_op_mov_reg_T0(OT_QUAD, R_ESP);
5200          } else if (s->ss32) {
5201              gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
5202              gen_op_mov_reg_T0(OT_LONG, R_ESP);
5203          } else {
5204              gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
5205              gen_op_mov_reg_T0(OT_WORD, R_ESP);
5206          }
5207          gen_pop_T0(s);
5208          if (CODE64(s)) {
5209              ot = dflag ? OT_QUAD : OT_WORD;
5210          } else {
5211              ot = dflag + OT_WORD;
5212          }
5213          gen_op_mov_reg_T0(ot, R_EBP);
5214          gen_pop_update(s);
5215          break;
5216      case 0x06: /* push es */
5217      case 0x0e: /* push cs */
5218      case 0x16: /* push ss */
5219      case 0x1e: /* push ds */
5220          if (CODE64(s))
5221              goto illegal_op;
5222          gen_op_movl_T0_seg(b >> 3);
5223          gen_push_T0(s);
5224          break;
5225      case 0x1a0: /* push fs */
5226      case 0x1a8: /* push gs */
5227          gen_op_movl_T0_seg((b >> 3) & 7);
5228          gen_push_T0(s);
5229          break;
5230      case 0x07: /* pop es */
5231      case 0x17: /* pop ss */
5232      case 0x1f: /* pop ds */
5233          if (CODE64(s))
5234              goto illegal_op;
5235          reg = b >> 3;
5236          gen_pop_T0(s);
5237          gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5238          gen_pop_update(s);
5239          if (reg == R_SS) {
5240              /* if reg == SS, inhibit interrupts/trace. */
5241              /* If several instructions disable interrupts, only the
5242                 _first_ does it */
5243              if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5244                  gen_helper_set_inhibit_irq(cpu_env);
5245              s->tf = 0;
5246          }
5247          if (s->is_jmp) {
5248              gen_jmp_im(s->pc - s->cs_base);
5249              gen_eob(s);
5250          }
5251          break;
5252      case 0x1a1: /* pop fs */
5253      case 0x1a9: /* pop gs */
5254          gen_pop_T0(s);
5255          gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
5256          gen_pop_update(s);
5257          if (s->is_jmp) {
5258              gen_jmp_im(s->pc - s->cs_base);
5259              gen_eob(s);
5260          }
5261          break;
5262  
5263          /**************************/
5264          /* mov */
5265      case 0x88:
5266      case 0x89: /* mov Gv, Ev */
5267          if ((b & 1) == 0)
5268              ot = OT_BYTE;
5269          else
5270              ot = dflag + OT_WORD;
5271          modrm = cpu_ldub_code(env, s->pc++);
5272          reg = ((modrm >> 3) & 7) | rex_r;
5273  
5274          /* generate a generic store */
5275          gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5276          break;
5277      case 0xc6:
5278      case 0xc7: /* mov Ev, Iv */
5279          if ((b & 1) == 0)
5280              ot = OT_BYTE;
5281          else
5282              ot = dflag + OT_WORD;
5283          modrm = cpu_ldub_code(env, s->pc++);
5284          mod = (modrm >> 6) & 3;
5285          if (mod != 3) {
5286              s->rip_offset = insn_const_size(ot);
5287              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5288          }
5289          val = insn_get(env, s, ot);
5290          gen_op_movl_T0_im(val);
5291          if (mod != 3)
5292              gen_op_st_T0_A0(ot + s->mem_index);
5293          else
5294              gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
5295          break;
5296      case 0x8a:
5297      case 0x8b: /* mov Ev, Gv */
5298          if ((b & 1) == 0)
5299              ot = OT_BYTE;
5300          else
5301              ot = OT_WORD + dflag;
5302          modrm = cpu_ldub_code(env, s->pc++);
5303          reg = ((modrm >> 3) & 7) | rex_r;
5304  
5305          gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5306          gen_op_mov_reg_T0(ot, reg);
5307          break;
5308      case 0x8e: /* mov seg, Gv */
5309          modrm = cpu_ldub_code(env, s->pc++);
5310          reg = (modrm >> 3) & 7;
5311          if (reg >= 6 || reg == R_CS)
5312              goto illegal_op;
5313          gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
5314          gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5315          if (reg == R_SS) {
5316              /* if reg == SS, inhibit interrupts/trace */
5317              /* If several instructions disable interrupts, only the
5318                 _first_ does it */
5319              if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5320                  gen_helper_set_inhibit_irq(cpu_env);
5321              s->tf = 0;
5322          }
5323          if (s->is_jmp) {
5324              gen_jmp_im(s->pc - s->cs_base);
5325              gen_eob(s);
5326          }
5327          break;
5328      case 0x8c: /* mov Gv, seg */
5329          modrm = cpu_ldub_code(env, s->pc++);
5330          reg = (modrm >> 3) & 7;
5331          mod = (modrm >> 6) & 3;
5332          if (reg >= 6)
5333              goto illegal_op;
5334          gen_op_movl_T0_seg(reg);
5335          if (mod == 3)
5336              ot = OT_WORD + dflag;
5337          else
5338              ot = OT_WORD;
5339          gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5340          break;
5341  
5342      case 0x1b6: /* movzbS Gv, Eb */
5343      case 0x1b7: /* movzwS Gv, Eb */
5344      case 0x1be: /* movsbS Gv, Eb */
5345      case 0x1bf: /* movswS Gv, Eb */
5346          {
5347              int d_ot;
5348              /* d_ot is the size of destination */
5349              d_ot = dflag + OT_WORD;
5350              /* ot is the size of source */
5351              ot = (b & 1) + OT_BYTE;
5352              modrm = cpu_ldub_code(env, s->pc++);
5353              reg = ((modrm >> 3) & 7) | rex_r;
5354              mod = (modrm >> 6) & 3;
5355              rm = (modrm & 7) | REX_B(s);
5356  
5357              if (mod == 3) {
5358                  gen_op_mov_TN_reg(ot, 0, rm);
5359                  switch(ot | (b & 8)) {
5360                  case OT_BYTE:
5361                      tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5362                      break;
5363                  case OT_BYTE | 8:
5364                      tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5365                      break;
5366                  case OT_WORD:
5367                      tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5368                      break;
5369                  default:
5370                  case OT_WORD | 8:
5371                      tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5372                      break;
5373                  }
5374                  gen_op_mov_reg_T0(d_ot, reg);
5375              } else {
5376                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5377                  if (b & 8) {
5378                      gen_op_lds_T0_A0(ot + s->mem_index);
5379                  } else {
5380                      gen_op_ldu_T0_A0(ot + s->mem_index);
5381                  }
5382                  gen_op_mov_reg_T0(d_ot, reg);
5383              }
5384          }
5385          break;
5386  
5387      case 0x8d: /* lea */
5388          ot = dflag + OT_WORD;
5389          modrm = cpu_ldub_code(env, s->pc++);
5390          mod = (modrm >> 6) & 3;
5391          if (mod == 3)
5392              goto illegal_op;
5393          reg = ((modrm >> 3) & 7) | rex_r;
5394          /* we must ensure that no segment is added */
5395          s->override = -1;
5396          val = s->addseg;
5397          s->addseg = 0;
5398          gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5399          s->addseg = val;
5400          gen_op_mov_reg_A0(ot - OT_WORD, reg);
5401          break;
5402  
5403      case 0xa0: /* mov EAX, Ov */
5404      case 0xa1:
5405      case 0xa2: /* mov Ov, EAX */
5406      case 0xa3:
5407          {
5408              target_ulong offset_addr;
5409  
5410              if ((b & 1) == 0)
5411                  ot = OT_BYTE;
5412              else
5413                  ot = dflag + OT_WORD;
5414  #ifdef TARGET_X86_64
5415              if (s->aflag == 2) {
5416                  offset_addr = cpu_ldq_code(env, s->pc);
5417                  s->pc += 8;
5418                  gen_op_movq_A0_im(offset_addr);
5419              } else
5420  #endif
5421              {
5422                  if (s->aflag) {
5423                      offset_addr = insn_get(env, s, OT_LONG);
5424                  } else {
5425                      offset_addr = insn_get(env, s, OT_WORD);
5426                  }
5427                  gen_op_movl_A0_im(offset_addr);
5428              }
5429              gen_add_A0_ds_seg(s);
5430              if ((b & 2) == 0) {
5431                  gen_op_ld_T0_A0(ot + s->mem_index);
5432                  gen_op_mov_reg_T0(ot, R_EAX);
5433              } else {
5434                  gen_op_mov_TN_reg(ot, 0, R_EAX);
5435                  gen_op_st_T0_A0(ot + s->mem_index);
5436              }
5437          }
5438          break;
5439      case 0xd7: /* xlat */
5440  #ifdef TARGET_X86_64
5441          if (s->aflag == 2) {
5442              gen_op_movq_A0_reg(R_EBX);
5443              gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
5444              tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5445              tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5446          } else
5447  #endif
5448          {
5449              gen_op_movl_A0_reg(R_EBX);
5450              gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
5451              tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
5452              tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5453              if (s->aflag == 0)
5454                  gen_op_andl_A0_ffff();
5455              else
5456                  tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
5457          }
5458          gen_add_A0_ds_seg(s);
5459          gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
5460          gen_op_mov_reg_T0(OT_BYTE, R_EAX);
5461          break;
5462      case 0xb0 ... 0xb7: /* mov R, Ib */
5463          val = insn_get(env, s, OT_BYTE);
5464          gen_op_movl_T0_im(val);
5465          gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
5466          break;
5467      case 0xb8 ... 0xbf: /* mov R, Iv */
5468  #ifdef TARGET_X86_64
5469          if (dflag == 2) {
5470              uint64_t tmp;
5471              /* 64 bit case */
5472              tmp = cpu_ldq_code(env, s->pc);
5473              s->pc += 8;
5474              reg = (b & 7) | REX_B(s);
5475              gen_movtl_T0_im(tmp);
5476              gen_op_mov_reg_T0(OT_QUAD, reg);
5477          } else
5478  #endif
5479          {
5480              ot = dflag ? OT_LONG : OT_WORD;
5481              val = insn_get(env, s, ot);
5482              reg = (b & 7) | REX_B(s);
5483              gen_op_movl_T0_im(val);
5484              gen_op_mov_reg_T0(ot, reg);
5485          }
5486          break;
5487  
5488      case 0x91 ... 0x97: /* xchg R, EAX */
5489          ot = dflag + OT_WORD;
5490          reg = (b & 7) | REX_B(s);
5491          rm = R_EAX;
5492          goto do_xchg_reg;
5493      case 0x86:
5494      case 0x87: /* xchg Ev, Gv */
5495          if ((b & 1) == 0)
5496              ot = OT_BYTE;
5497          else
5498              ot = dflag + OT_WORD;
5499          modrm = cpu_ldub_code(env, s->pc++);
5500          reg = ((modrm >> 3) & 7) | rex_r;
5501          mod = (modrm >> 6) & 3;
5502          if (mod == 3) {
5503              rm = (modrm & 7) | REX_B(s);
5504          do_xchg_reg:
5505              gen_op_mov_TN_reg(ot, 0, reg);
5506              gen_op_mov_TN_reg(ot, 1, rm);
5507              gen_op_mov_reg_T0(ot, rm);
5508              gen_op_mov_reg_T1(ot, reg);
5509          } else {
5510              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5511              gen_op_mov_TN_reg(ot, 0, reg);
5512              /* for xchg, lock is implicit */
5513              if (!(prefixes & PREFIX_LOCK))
5514                  gen_helper_lock();
5515              gen_op_ld_T1_A0(ot + s->mem_index);
5516              gen_op_st_T0_A0(ot + s->mem_index);
5517              if (!(prefixes & PREFIX_LOCK))
5518                  gen_helper_unlock();
5519              gen_op_mov_reg_T1(ot, reg);
5520          }
5521          break;
5522      case 0xc4: /* les Gv */
5523          if (CODE64(s))
5524              goto illegal_op;
5525          op = R_ES;
5526          goto do_lxx;
5527      case 0xc5: /* lds Gv */
5528          if (CODE64(s))
5529              goto illegal_op;
5530          op = R_DS;
5531          goto do_lxx;
5532      case 0x1b2: /* lss Gv */
5533          op = R_SS;
5534          goto do_lxx;
5535      case 0x1b4: /* lfs Gv */
5536          op = R_FS;
5537          goto do_lxx;
5538      case 0x1b5: /* lgs Gv */
5539          op = R_GS;
5540      do_lxx:
5541          ot = dflag ? OT_LONG : OT_WORD;
5542          modrm = cpu_ldub_code(env, s->pc++);
5543          reg = ((modrm >> 3) & 7) | rex_r;
5544          mod = (modrm >> 6) & 3;
5545          if (mod == 3)
5546              goto illegal_op;
5547          gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5548          gen_op_ld_T1_A0(ot + s->mem_index);
5549          gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
5550          /* load the segment first to handle exceptions properly */
5551          gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
5552          gen_movl_seg_T0(s, op, pc_start - s->cs_base);
5553          /* then put the data */
5554          gen_op_mov_reg_T1(ot, reg);
5555          if (s->is_jmp) {
5556              gen_jmp_im(s->pc - s->cs_base);
5557              gen_eob(s);
5558          }
5559          break;
5560  
5561          /************************/
5562          /* shifts */
5563      case 0xc0:
5564      case 0xc1:
5565          /* shift Ev,Ib */
5566          shift = 2;
5567      grp2:
5568          {
5569              if ((b & 1) == 0)
5570                  ot = OT_BYTE;
5571              else
5572                  ot = dflag + OT_WORD;
5573  
5574              modrm = cpu_ldub_code(env, s->pc++);
5575              mod = (modrm >> 6) & 3;
5576              op = (modrm >> 3) & 7;
5577  
5578              if (mod != 3) {
5579                  if (shift == 2) {
5580                      s->rip_offset = 1;
5581                  }
5582                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5583                  opreg = OR_TMP0;
5584              } else {
5585                  opreg = (modrm & 7) | REX_B(s);
5586              }
5587  
5588              /* simpler op */
5589              if (shift == 0) {
5590                  gen_shift(s, op, ot, opreg, OR_ECX);
5591              } else {
5592                  if (shift == 2) {
5593                      shift = cpu_ldub_code(env, s->pc++);
5594                  }
5595                  gen_shifti(s, op, ot, opreg, shift);
5596              }
5597          }
5598          break;
5599      case 0xd0:
5600      case 0xd1:
5601          /* shift Ev,1 */
5602          shift = 1;
5603          goto grp2;
5604      case 0xd2:
5605      case 0xd3:
5606          /* shift Ev,cl */
5607          shift = 0;
5608          goto grp2;
5609  
5610      case 0x1a4: /* shld imm */
5611          op = 0;
5612          shift = 1;
5613          goto do_shiftd;
5614      case 0x1a5: /* shld cl */
5615          op = 0;
5616          shift = 0;
5617          goto do_shiftd;
5618      case 0x1ac: /* shrd imm */
5619          op = 1;
5620          shift = 1;
5621          goto do_shiftd;
5622      case 0x1ad: /* shrd cl */
5623          op = 1;
5624          shift = 0;
5625      do_shiftd:
5626          ot = dflag + OT_WORD;
5627          modrm = cpu_ldub_code(env, s->pc++);
5628          mod = (modrm >> 6) & 3;
5629          rm = (modrm & 7) | REX_B(s);
5630          reg = ((modrm >> 3) & 7) | rex_r;
5631          if (mod != 3) {
5632              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5633              opreg = OR_TMP0;
5634          } else {
5635              opreg = rm;
5636          }
5637          gen_op_mov_TN_reg(ot, 1, reg);
5638  
5639          if (shift) {
5640              val = cpu_ldub_code(env, s->pc++);
5641              tcg_gen_movi_tl(cpu_T3, val);
5642          } else {
5643              tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUX86State, regs[R_ECX]));
5644          }
5645          gen_shiftd_rm_T1_T3(s, ot, opreg, op);
5646          break;
5647  
5648          /************************/
5649          /* floats */
5650      case 0xd8 ... 0xdf:
5651          if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5652              /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5653              /* XXX: what to do if illegal op ? */
5654              gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5655              break;
5656          }
5657          modrm = cpu_ldub_code(env, s->pc++);
5658          mod = (modrm >> 6) & 3;
5659          rm = modrm & 7;
5660          op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5661          if (mod != 3) {
5662              /* memory op */
5663              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
5664              switch(op) {
5665              case 0x00 ... 0x07: /* fxxxs */
5666              case 0x10 ... 0x17: /* fixxxl */
5667              case 0x20 ... 0x27: /* fxxxl */
5668              case 0x30 ... 0x37: /* fixxx */
5669                  {
5670                      int op1;
5671                      op1 = op & 7;
5672  
5673                      switch(op >> 4) {
5674                      case 0:
5675                          gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5676                          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5677                          gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5678                          break;
5679                      case 1:
5680                          gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5681                          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5682                          gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5683                          break;
5684                      case 2:
5685                          tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
5686                                            (s->mem_index >> 2) - 1);
5687                          gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5688                          break;
5689                      case 3:
5690                      default:
5691                          gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5692                          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5693                          gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5694                          break;
5695                      }
5696  
5697                      gen_helper_fp_arith_ST0_FT0(op1);
5698                      if (op1 == 3) {
5699                          /* fcomp needs pop */
5700                          gen_helper_fpop(cpu_env);
5701                      }
5702                  }
5703                  break;
5704              case 0x08: /* flds */
5705              case 0x0a: /* fsts */
5706              case 0x0b: /* fstps */
5707              case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5708              case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5709              case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5710                  switch(op & 7) {
5711                  case 0:
5712                      switch(op >> 4) {
5713                      case 0:
5714                          gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5715                          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5716                          gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5717                          break;
5718                      case 1:
5719                          gen_op_ld_T0_A0(OT_LONG + s->mem_index);
5720                          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5721                          gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5722                          break;
5723                      case 2:
5724                          tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
5725                                            (s->mem_index >> 2) - 1);
5726                          gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5727                          break;
5728                      case 3:
5729                      default:
5730                          gen_op_lds_T0_A0(OT_WORD + s->mem_index);
5731                          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5732                          gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5733                          break;
5734                      }
5735                      break;
5736                  case 1:
5737                      /* XXX: the corresponding CPUID bit must be tested ! */
5738                      switch(op >> 4) {
5739                      case 1:
5740                          gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5741                          tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5742                          gen_op_st_T0_A0(OT_LONG + s->mem_index);
5743                          break;
5744                      case 2:
5745                          gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5746                          tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
5747                                            (s->mem_index >> 2) - 1);
5748                          break;
5749                      case 3:
5750                      default:
5751                          gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5752                          tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5753                          gen_op_st_T0_A0(OT_WORD + s->mem_index);
5754                          break;
5755                      }
5756                      gen_helper_fpop(cpu_env);
5757                      break;
5758                  default:
5759                      switch(op >> 4) {
5760                      case 0:
5761                          gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5762                          tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5763                          gen_op_st_T0_A0(OT_LONG + s->mem_index);
5764                          break;
5765                      case 1:
5766                          gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5767                          tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5768                          gen_op_st_T0_A0(OT_LONG + s->mem_index);
5769                          break;
5770                      case 2:
5771                          gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5772                          tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
5773                                            (s->mem_index >> 2) - 1);
5774                          break;
5775                      case 3:
5776                      default:
5777                          gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5778                          tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5779                          gen_op_st_T0_A0(OT_WORD + s->mem_index);
5780                          break;
5781                      }
5782                      if ((op & 7) == 3)
5783                          gen_helper_fpop(cpu_env);
5784                      break;
5785                  }
5786                  break;
5787              case 0x0c: /* fldenv mem */
5788                  gen_update_cc_op(s);
5789                  gen_jmp_im(pc_start - s->cs_base);
5790                  gen_helper_fldenv(cpu_env,
5791                                     cpu_A0, tcg_const_i32(s->dflag));
5792                  break;
5793              case 0x0d: /* fldcw mem */
5794                  gen_op_ld_T0_A0(OT_WORD + s->mem_index);
5795                  tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5796                  gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5797                  break;
5798              case 0x0e: /* fnstenv mem */
5799                  gen_update_cc_op(s);
5800                  gen_jmp_im(pc_start - s->cs_base);
5801                  gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
5802                  break;
5803              case 0x0f: /* fnstcw mem */
5804                  gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5805                  tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5806                  gen_op_st_T0_A0(OT_WORD + s->mem_index);
5807                  break;
5808              case 0x1d: /* fldt mem */
5809                  gen_update_cc_op(s);
5810                  gen_jmp_im(pc_start - s->cs_base);
5811                  gen_helper_fldt_ST0(cpu_env, cpu_A0);
5812                  break;
5813              case 0x1f: /* fstpt mem */
5814                  gen_update_cc_op(s);
5815                  gen_jmp_im(pc_start - s->cs_base);
5816                  gen_helper_fstt_ST0(cpu_env, cpu_A0);
5817                  gen_helper_fpop(cpu_env);
5818                  break;
5819              case 0x2c: /* frstor mem */
5820                  gen_update_cc_op(s);
5821                  gen_jmp_im(pc_start - s->cs_base);
5822                  gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
5823                  break;
5824              case 0x2e: /* fnsave mem */
5825                  gen_update_cc_op(s);
5826                  gen_jmp_im(pc_start - s->cs_base);
5827                  gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
5828                  break;
5829              case 0x2f: /* fnstsw mem */
5830                  gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5831                  tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5832                  gen_op_st_T0_A0(OT_WORD + s->mem_index);
5833                  break;
5834              case 0x3c: /* fbld */
5835                  gen_update_cc_op(s);
5836                  gen_jmp_im(pc_start - s->cs_base);
5837                  gen_helper_fbld_ST0(cpu_env, cpu_A0);
5838                  break;
5839              case 0x3e: /* fbstp */
5840                  gen_update_cc_op(s);
5841                  gen_jmp_im(pc_start - s->cs_base);
5842                  gen_helper_fbst_ST0(cpu_env, cpu_A0);
5843                  gen_helper_fpop(cpu_env);
5844                  break;
5845              case 0x3d: /* fildll */
5846                  tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
5847                                    (s->mem_index >> 2) - 1);
5848                  gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5849                  break;
5850              case 0x3f: /* fistpll */
5851                  gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5852                  tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
5853                                    (s->mem_index >> 2) - 1);
5854                  gen_helper_fpop(cpu_env);
5855                  break;
5856              default:
5857                  goto illegal_op;
5858              }
5859          } else {
5860              /* register float ops */
5861              opreg = rm;
5862  
5863              switch(op) {
5864              case 0x08: /* fld sti */
5865                  gen_helper_fpush(cpu_env);
5866                  gen_helper_fmov_ST0_STN(cpu_env,
5867                                          tcg_const_i32((opreg + 1) & 7));
5868                  break;
5869              case 0x09: /* fxchg sti */
5870              case 0x29: /* fxchg4 sti, undocumented op */
5871              case 0x39: /* fxchg7 sti, undocumented op */
5872                  gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5873                  break;
5874              case 0x0a: /* grp d9/2 */
5875                  switch(rm) {
5876                  case 0: /* fnop */
5877                      /* check exceptions (FreeBSD FPU probe) */
5878                      gen_update_cc_op(s);
5879                      gen_jmp_im(pc_start - s->cs_base);
5880                      gen_helper_fwait(cpu_env);
5881                      break;
5882                  default:
5883                      goto illegal_op;
5884                  }
5885                  break;
5886              case 0x0c: /* grp d9/4 */
5887                  switch(rm) {
5888                  case 0: /* fchs */
5889                      gen_helper_fchs_ST0(cpu_env);
5890                      break;
5891                  case 1: /* fabs */
5892                      gen_helper_fabs_ST0(cpu_env);
5893                      break;
5894                  case 4: /* ftst */
5895                      gen_helper_fldz_FT0(cpu_env);
5896                      gen_helper_fcom_ST0_FT0(cpu_env);
5897                      break;
5898                  case 5: /* fxam */
5899                      gen_helper_fxam_ST0(cpu_env);
5900                      break;
5901                  default:
5902                      goto illegal_op;
5903                  }
5904                  break;
5905              case 0x0d: /* grp d9/5 */
5906                  {
5907                      switch(rm) {
5908                      case 0:
5909                          gen_helper_fpush(cpu_env);
5910                          gen_helper_fld1_ST0(cpu_env);
5911                          break;
5912                      case 1:
5913                          gen_helper_fpush(cpu_env);
5914                          gen_helper_fldl2t_ST0(cpu_env);
5915                          break;
5916                      case 2:
5917                          gen_helper_fpush(cpu_env);
5918                          gen_helper_fldl2e_ST0(cpu_env);
5919                          break;
5920                      case 3:
5921                          gen_helper_fpush(cpu_env);
5922                          gen_helper_fldpi_ST0(cpu_env);
5923                          break;
5924                      case 4:
5925                          gen_helper_fpush(cpu_env);
5926                          gen_helper_fldlg2_ST0(cpu_env);
5927                          break;
5928                      case 5:
5929                          gen_helper_fpush(cpu_env);
5930                          gen_helper_fldln2_ST0(cpu_env);
5931                          break;
5932                      case 6:
5933                          gen_helper_fpush(cpu_env);
5934                          gen_helper_fldz_ST0(cpu_env);
5935                          break;
5936                      default:
5937                          goto illegal_op;
5938                      }
5939                  }
5940                  break;
5941              case 0x0e: /* grp d9/6 */
5942                  switch(rm) {
5943                  case 0: /* f2xm1 */
5944                      gen_helper_f2xm1(cpu_env);
5945                      break;
5946                  case 1: /* fyl2x */
5947                      gen_helper_fyl2x(cpu_env);
5948                      break;
5949                  case 2: /* fptan */
5950                      gen_helper_fptan(cpu_env);
5951                      break;
5952                  case 3: /* fpatan */
5953                      gen_helper_fpatan(cpu_env);
5954                      break;
5955                  case 4: /* fxtract */
5956                      gen_helper_fxtract(cpu_env);
5957                      break;
5958                  case 5: /* fprem1 */
5959                      gen_helper_fprem1(cpu_env);
5960                      break;
5961                  case 6: /* fdecstp */
5962                      gen_helper_fdecstp(cpu_env);
5963                      break;
5964                  default:
5965                  case 7: /* fincstp */
5966                      gen_helper_fincstp(cpu_env);
5967                      break;
5968                  }
5969                  break;
5970              case 0x0f: /* grp d9/7 */
5971                  switch(rm) {
5972                  case 0: /* fprem */
5973                      gen_helper_fprem(cpu_env);
5974                      break;
5975                  case 1: /* fyl2xp1 */
5976                      gen_helper_fyl2xp1(cpu_env);
5977                      break;
5978                  case 2: /* fsqrt */
5979                      gen_helper_fsqrt(cpu_env);
5980                      break;
5981                  case 3: /* fsincos */
5982                      gen_helper_fsincos(cpu_env);
5983                      break;
5984                  case 5: /* fscale */
5985                      gen_helper_fscale(cpu_env);
5986                      break;
5987                  case 4: /* frndint */
5988                      gen_helper_frndint(cpu_env);
5989                      break;
5990                  case 6: /* fsin */
5991                      gen_helper_fsin(cpu_env);
5992                      break;
5993                  default:
5994                  case 7: /* fcos */
5995                      gen_helper_fcos(cpu_env);
5996                      break;
5997                  }
5998                  break;
5999              case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6000              case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6001              case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6002                  {
6003                      int op1;
6004  
6005                      op1 = op & 7;
6006                      if (op >= 0x20) {
6007                          gen_helper_fp_arith_STN_ST0(op1, opreg);
6008                          if (op >= 0x30)
6009                              gen_helper_fpop(cpu_env);
6010                      } else {
6011                          gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6012                          gen_helper_fp_arith_ST0_FT0(op1);
6013                      }
6014                  }
6015                  break;
6016              case 0x02: /* fcom */
6017              case 0x22: /* fcom2, undocumented op */
6018                  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6019                  gen_helper_fcom_ST0_FT0(cpu_env);
6020                  break;
6021              case 0x03: /* fcomp */
6022              case 0x23: /* fcomp3, undocumented op */
6023              case 0x32: /* fcomp5, undocumented op */
6024                  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6025                  gen_helper_fcom_ST0_FT0(cpu_env);
6026                  gen_helper_fpop(cpu_env);
6027                  break;
6028              case 0x15: /* da/5 */
6029                  switch(rm) {
6030                  case 1: /* fucompp */
6031                      gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6032                      gen_helper_fucom_ST0_FT0(cpu_env);
6033                      gen_helper_fpop(cpu_env);
6034                      gen_helper_fpop(cpu_env);
6035                      break;
6036                  default:
6037                      goto illegal_op;
6038                  }
6039                  break;
6040              case 0x1c:
6041                  switch(rm) {
6042                  case 0: /* feni (287 only, just do nop here) */
6043                      break;
6044                  case 1: /* fdisi (287 only, just do nop here) */
6045                      break;
6046                  case 2: /* fclex */
6047                      gen_helper_fclex(cpu_env);
6048                      break;
6049                  case 3: /* fninit */
6050                      gen_helper_fninit(cpu_env);
6051                      break;
6052                  case 4: /* fsetpm (287 only, just do nop here) */
6053                      break;
6054                  default:
6055                      goto illegal_op;
6056                  }
6057                  break;
6058              case 0x1d: /* fucomi */
6059                  gen_update_cc_op(s);
6060                  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6061                  gen_helper_fucomi_ST0_FT0(cpu_env);
6062                  set_cc_op(s, CC_OP_EFLAGS);
6063                  break;
6064              case 0x1e: /* fcomi */
6065                  gen_update_cc_op(s);
6066                  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6067                  gen_helper_fcomi_ST0_FT0(cpu_env);
6068                  set_cc_op(s, CC_OP_EFLAGS);
6069                  break;
6070              case 0x28: /* ffree sti */
6071                  gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6072                  break;
6073              case 0x2a: /* fst sti */
6074                  gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6075                  break;
6076              case 0x2b: /* fstp sti */
6077              case 0x0b: /* fstp1 sti, undocumented op */
6078              case 0x3a: /* fstp8 sti, undocumented op */
6079              case 0x3b: /* fstp9 sti, undocumented op */
6080                  gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6081                  gen_helper_fpop(cpu_env);
6082                  break;
6083              case 0x2c: /* fucom st(i) */
6084                  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6085                  gen_helper_fucom_ST0_FT0(cpu_env);
6086                  break;
6087              case 0x2d: /* fucomp st(i) */
6088                  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6089                  gen_helper_fucom_ST0_FT0(cpu_env);
6090                  gen_helper_fpop(cpu_env);
6091                  break;
6092              case 0x33: /* de/3 */
6093                  switch(rm) {
6094                  case 1: /* fcompp */
6095                      gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6096                      gen_helper_fcom_ST0_FT0(cpu_env);
6097                      gen_helper_fpop(cpu_env);
6098                      gen_helper_fpop(cpu_env);
6099                      break;
6100                  default:
6101                      goto illegal_op;
6102                  }
6103                  break;
6104              case 0x38: /* ffreep sti, undocumented op */
6105                  gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6106                  gen_helper_fpop(cpu_env);
6107                  break;
6108              case 0x3c: /* df/4 */
6109                  switch(rm) {
6110                  case 0:
6111                      gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6112                      tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6113                      gen_op_mov_reg_T0(OT_WORD, R_EAX);
6114                      break;
6115                  default:
6116                      goto illegal_op;
6117                  }
6118                  break;
6119              case 0x3d: /* fucomip */
6120                  gen_update_cc_op(s);
6121                  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6122                  gen_helper_fucomi_ST0_FT0(cpu_env);
6123                  gen_helper_fpop(cpu_env);
6124                  set_cc_op(s, CC_OP_EFLAGS);
6125                  break;
6126              case 0x3e: /* fcomip */
6127                  gen_update_cc_op(s);
6128                  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6129                  gen_helper_fcomi_ST0_FT0(cpu_env);
6130                  gen_helper_fpop(cpu_env);
6131                  set_cc_op(s, CC_OP_EFLAGS);
6132                  break;
6133              case 0x10 ... 0x13: /* fcmovxx */
6134              case 0x18 ... 0x1b:
6135                  {
6136                      int op1, l1;
6137                      static const uint8_t fcmov_cc[8] = {
6138                          (JCC_B << 1),
6139                          (JCC_Z << 1),
6140                          (JCC_BE << 1),
6141                          (JCC_P << 1),
6142                      };
6143                      op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6144                      l1 = gen_new_label();
6145                      gen_jcc1(s, op1, l1);
6146                      gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6147                      gen_set_label(l1);
6148                  }
6149                  break;
6150              default:
6151                  goto illegal_op;
6152              }
6153          }
6154          break;
6155          /************************/
6156          /* string ops */
6157  
6158      case 0xa4: /* movsS */
6159      case 0xa5:
6160          if ((b & 1) == 0)
6161              ot = OT_BYTE;
6162          else
6163              ot = dflag + OT_WORD;
6164  
6165          if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6166              gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6167          } else {
6168              gen_movs(s, ot);
6169          }
6170          break;
6171  
6172      case 0xaa: /* stosS */
6173      case 0xab:
6174          if ((b & 1) == 0)
6175              ot = OT_BYTE;
6176          else
6177              ot = dflag + OT_WORD;
6178  
6179          if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6180              gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6181          } else {
6182              gen_stos(s, ot);
6183          }
6184          break;
6185      case 0xac: /* lodsS */
6186      case 0xad:
6187          if ((b & 1) == 0)
6188              ot = OT_BYTE;
6189          else
6190              ot = dflag + OT_WORD;
6191          if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6192              gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6193          } else {
6194              gen_lods(s, ot);
6195          }
6196          break;
6197      case 0xae: /* scasS */
6198      case 0xaf:
6199          if ((b & 1) == 0)
6200              ot = OT_BYTE;
6201          else
6202              ot = dflag + OT_WORD;
6203          if (prefixes & PREFIX_REPNZ) {
6204              gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6205          } else if (prefixes & PREFIX_REPZ) {
6206              gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6207          } else {
6208              gen_scas(s, ot);
6209              set_cc_op(s, CC_OP_SUBB + ot);
6210          }
6211          break;
6212  
6213      case 0xa6: /* cmpsS */
6214      case 0xa7:
6215          if ((b & 1) == 0)
6216              ot = OT_BYTE;
6217          else
6218              ot = dflag + OT_WORD;
6219          if (prefixes & PREFIX_REPNZ) {
6220              gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6221          } else if (prefixes & PREFIX_REPZ) {
6222              gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6223          } else {
6224              gen_cmps(s, ot);
6225              set_cc_op(s, CC_OP_SUBB + ot);
6226          }
6227          break;
6228      case 0x6c: /* insS */
6229      case 0x6d:
6230          if ((b & 1) == 0)
6231              ot = OT_BYTE;
6232          else
6233              ot = dflag ? OT_LONG : OT_WORD;
6234          gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6235          gen_op_andl_T0_ffff();
6236          gen_check_io(s, ot, pc_start - s->cs_base,
6237                       SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6238          if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6239              gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6240          } else {
6241              gen_ins(s, ot);
6242              if (use_icount) {
6243                  gen_jmp(s, s->pc - s->cs_base);
6244              }
6245          }
6246          break;
6247      case 0x6e: /* outsS */
6248      case 0x6f:
6249          if ((b & 1) == 0)
6250              ot = OT_BYTE;
6251          else
6252              ot = dflag ? OT_LONG : OT_WORD;
6253          gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6254          gen_op_andl_T0_ffff();
6255          gen_check_io(s, ot, pc_start - s->cs_base,
6256                       svm_is_rep(prefixes) | 4);
6257          if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6258              gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6259          } else {
6260              gen_outs(s, ot);
6261              if (use_icount) {
6262                  gen_jmp(s, s->pc - s->cs_base);
6263              }
6264          }
6265          break;
6266  
6267          /************************/
6268          /* port I/O */
6269  
6270      case 0xe4:
6271      case 0xe5:
6272          if ((b & 1) == 0)
6273              ot = OT_BYTE;
6274          else
6275              ot = dflag ? OT_LONG : OT_WORD;
6276          val = cpu_ldub_code(env, s->pc++);
6277          gen_op_movl_T0_im(val);
6278          gen_check_io(s, ot, pc_start - s->cs_base,
6279                       SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6280          if (use_icount)
6281              gen_io_start();
6282          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6283          gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6284          gen_op_mov_reg_T1(ot, R_EAX);
6285          if (use_icount) {
6286              gen_io_end();
6287              gen_jmp(s, s->pc - s->cs_base);
6288          }
6289          break;
6290      case 0xe6:
6291      case 0xe7:
6292          if ((b & 1) == 0)
6293              ot = OT_BYTE;
6294          else
6295              ot = dflag ? OT_LONG : OT_WORD;
6296          val = cpu_ldub_code(env, s->pc++);
6297          gen_op_movl_T0_im(val);
6298          gen_check_io(s, ot, pc_start - s->cs_base,
6299                       svm_is_rep(prefixes));
6300          gen_op_mov_TN_reg(ot, 1, R_EAX);
6301  
6302          if (use_icount)
6303              gen_io_start();
6304          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6305          tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
6306          tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6307          gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6308          if (use_icount) {
6309              gen_io_end();
6310              gen_jmp(s, s->pc - s->cs_base);
6311          }
6312          break;
6313      case 0xec:
6314      case 0xed:
6315          if ((b & 1) == 0)
6316              ot = OT_BYTE;
6317          else
6318              ot = dflag ? OT_LONG : OT_WORD;
6319          gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6320          gen_op_andl_T0_ffff();
6321          gen_check_io(s, ot, pc_start - s->cs_base,
6322                       SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6323          if (use_icount)
6324              gen_io_start();
6325          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6326          gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6327          gen_op_mov_reg_T1(ot, R_EAX);
6328          if (use_icount) {
6329              gen_io_end();
6330              gen_jmp(s, s->pc - s->cs_base);
6331          }
6332          break;
6333      case 0xee:
6334      case 0xef:
6335          if ((b & 1) == 0)
6336              ot = OT_BYTE;
6337          else
6338              ot = dflag ? OT_LONG : OT_WORD;
6339          gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
6340          gen_op_andl_T0_ffff();
6341          gen_check_io(s, ot, pc_start - s->cs_base,
6342                       svm_is_rep(prefixes));
6343          gen_op_mov_TN_reg(ot, 1, R_EAX);
6344  
6345          if (use_icount)
6346              gen_io_start();
6347          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6348          tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
6349          tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6350          gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6351          if (use_icount) {
6352              gen_io_end();
6353              gen_jmp(s, s->pc - s->cs_base);
6354          }
6355          break;
6356  
6357          /************************/
6358          /* control */
6359      case 0xc2: /* ret im */
6360          val = cpu_ldsw_code(env, s->pc);
6361          s->pc += 2;
6362          gen_pop_T0(s);
6363          if (CODE64(s) && s->dflag)
6364              s->dflag = 2;
6365          gen_stack_update(s, val + (2 << s->dflag));
6366          if (s->dflag == 0)
6367              gen_op_andl_T0_ffff();
6368          gen_op_jmp_T0();
6369          gen_eob(s);
6370          break;
6371      case 0xc3: /* ret */
6372          gen_pop_T0(s);
6373          gen_pop_update(s);
6374          if (s->dflag == 0)
6375              gen_op_andl_T0_ffff();
6376          gen_op_jmp_T0();
6377          gen_eob(s);
6378          break;
6379      case 0xca: /* lret im */
6380          val = cpu_ldsw_code(env, s->pc);
6381          s->pc += 2;
6382      do_lret:
6383          if (s->pe && !s->vm86) {
6384              gen_update_cc_op(s);
6385              gen_jmp_im(pc_start - s->cs_base);
6386              gen_helper_lret_protected(cpu_env, tcg_const_i32(s->dflag),
6387                                        tcg_const_i32(val));
6388          } else {
6389              gen_stack_A0(s);
6390              /* pop offset */
6391              gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6392              if (s->dflag == 0)
6393                  gen_op_andl_T0_ffff();
6394              /* NOTE: keeping EIP updated is not a problem in case of
6395                 exception */
6396              gen_op_jmp_T0();
6397              /* pop selector */
6398              gen_op_addl_A0_im(2 << s->dflag);
6399              gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
6400              gen_op_movl_seg_T0_vm(R_CS);
6401              /* add stack offset */
6402              gen_stack_update(s, val + (4 << s->dflag));
6403          }
6404          gen_eob(s);
6405          break;
6406      case 0xcb: /* lret */
6407          val = 0;
6408          goto do_lret;
6409      case 0xcf: /* iret */
6410          gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6411          if (!s->pe) {
6412              /* real mode */
6413              gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag));
6414              set_cc_op(s, CC_OP_EFLAGS);
6415          } else if (s->vm86) {
6416              if (s->iopl != 3) {
6417                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6418              } else {
6419                  gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag));
6420                  set_cc_op(s, CC_OP_EFLAGS);
6421              }
6422          } else {
6423              gen_update_cc_op(s);
6424              gen_jmp_im(pc_start - s->cs_base);
6425              gen_helper_iret_protected(cpu_env, tcg_const_i32(s->dflag),
6426                                        tcg_const_i32(s->pc - s->cs_base));
6427              set_cc_op(s, CC_OP_EFLAGS);
6428          }
6429          gen_eob(s);
6430          break;
6431      case 0xe8: /* call im */
6432          {
6433              if (dflag)
6434                  tval = (int32_t)insn_get(env, s, OT_LONG);
6435              else
6436                  tval = (int16_t)insn_get(env, s, OT_WORD);
6437              next_eip = s->pc - s->cs_base;
6438              tval += next_eip;
6439              if (s->dflag == 0)
6440                  tval &= 0xffff;
6441              gen_movtl_T0_im(next_eip);
6442              gen_push_T0(s);
6443              gen_jmp(s, tval);
6444          }
6445          break;
6446      case 0x9a: /* lcall im */
6447          {
6448              unsigned int selector, offset;
6449  
6450              if (CODE64(s))
6451                  goto illegal_op;
6452              ot = dflag ? OT_LONG : OT_WORD;
6453              offset = insn_get(env, s, ot);
6454              selector = insn_get(env, s, OT_WORD);
6455  
6456              gen_op_movl_T0_im(selector);
6457              gen_op_movl_T1_imu(offset);
6458          }
6459          goto do_lcall;
6460      case 0xe9: /* jmp im */
6461          if (dflag)
6462              tval = (int32_t)insn_get(env, s, OT_LONG);
6463          else
6464              tval = (int16_t)insn_get(env, s, OT_WORD);
6465          tval += s->pc - s->cs_base;
6466          if (s->dflag == 0)
6467              tval &= 0xffff;
6468          else if(!CODE64(s))
6469              tval &= 0xffffffff;
6470          gen_jmp(s, tval);
6471          break;
6472      case 0xea: /* ljmp im */
6473          {
6474              unsigned int selector, offset;
6475  
6476              if (CODE64(s))
6477                  goto illegal_op;
6478              ot = dflag ? OT_LONG : OT_WORD;
6479              offset = insn_get(env, s, ot);
6480              selector = insn_get(env, s, OT_WORD);
6481  
6482              gen_op_movl_T0_im(selector);
6483              gen_op_movl_T1_imu(offset);
6484          }
6485          goto do_ljmp;
6486      case 0xeb: /* jmp Jb */
6487          tval = (int8_t)insn_get(env, s, OT_BYTE);
6488          tval += s->pc - s->cs_base;
6489          if (s->dflag == 0)
6490              tval &= 0xffff;
6491          gen_jmp(s, tval);
6492          break;
6493      case 0x70 ... 0x7f: /* jcc Jb */
6494          tval = (int8_t)insn_get(env, s, OT_BYTE);
6495          goto do_jcc;
6496      case 0x180 ... 0x18f: /* jcc Jv */
6497          if (dflag) {
6498              tval = (int32_t)insn_get(env, s, OT_LONG);
6499          } else {
6500              tval = (int16_t)insn_get(env, s, OT_WORD);
6501          }
6502      do_jcc:
6503          next_eip = s->pc - s->cs_base;
6504          tval += next_eip;
6505          if (s->dflag == 0)
6506              tval &= 0xffff;
6507          gen_jcc(s, b, tval, next_eip);
6508          break;
6509  
6510      case 0x190 ... 0x19f: /* setcc Gv */
6511          modrm = cpu_ldub_code(env, s->pc++);
6512          gen_setcc(s, b);
6513          gen_ldst_modrm(env, s, modrm, OT_BYTE, OR_TMP0, 1);
6514          break;
6515      case 0x140 ... 0x14f: /* cmov Gv, Ev */
6516          {
6517              int l1;
6518              TCGv t0;
6519  
6520              ot = dflag + OT_WORD;
6521              modrm = cpu_ldub_code(env, s->pc++);
6522              reg = ((modrm >> 3) & 7) | rex_r;
6523              mod = (modrm >> 6) & 3;
6524              t0 = tcg_temp_local_new();
6525              if (mod != 3) {
6526                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6527                  gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
6528              } else {
6529                  rm = (modrm & 7) | REX_B(s);
6530                  gen_op_mov_v_reg(ot, t0, rm);
6531              }
6532  #ifdef TARGET_X86_64
6533              if (ot == OT_LONG) {
6534                  /* XXX: specific Intel behaviour ? */
6535                  l1 = gen_new_label();
6536                  gen_jcc1(s, b ^ 1, l1);
6537                  tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET);
6538                  gen_set_label(l1);
6539                  tcg_gen_movi_tl(cpu_tmp0, 0);
6540                  tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_LH_OFFSET);
6541              } else
6542  #endif
6543              {
6544                  l1 = gen_new_label();
6545                  gen_jcc1(s, b ^ 1, l1);
6546                  gen_op_mov_reg_v(ot, reg, t0);
6547                  gen_set_label(l1);
6548              }
6549              tcg_temp_free(t0);
6550          }
6551          break;
6552  
6553          /************************/
6554          /* flags */
6555      case 0x9c: /* pushf */
6556          gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6557          if (s->vm86 && s->iopl != 3) {
6558              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6559          } else {
6560              gen_update_cc_op(s);
6561              gen_helper_read_eflags(cpu_T[0], cpu_env);
6562              gen_push_T0(s);
6563          }
6564          break;
6565      case 0x9d: /* popf */
6566          gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6567          if (s->vm86 && s->iopl != 3) {
6568              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6569          } else {
6570              gen_pop_T0(s);
6571              if (s->cpl == 0) {
6572                  if (s->dflag) {
6573                      gen_helper_write_eflags(cpu_env, cpu_T[0],
6574                                              tcg_const_i32((TF_MASK | AC_MASK |
6575                                                             ID_MASK | NT_MASK |
6576                                                             IF_MASK |
6577                                                             IOPL_MASK)));
6578                  } else {
6579                      gen_helper_write_eflags(cpu_env, cpu_T[0],
6580                                              tcg_const_i32((TF_MASK | AC_MASK |
6581                                                             ID_MASK | NT_MASK |
6582                                                             IF_MASK | IOPL_MASK)
6583                                                            & 0xffff));
6584                  }
6585              } else {
6586                  if (s->cpl <= s->iopl) {
6587                      if (s->dflag) {
6588                          gen_helper_write_eflags(cpu_env, cpu_T[0],
6589                                                  tcg_const_i32((TF_MASK |
6590                                                                 AC_MASK |
6591                                                                 ID_MASK |
6592                                                                 NT_MASK |
6593                                                                 IF_MASK)));
6594                      } else {
6595                          gen_helper_write_eflags(cpu_env, cpu_T[0],
6596                                                  tcg_const_i32((TF_MASK |
6597                                                                 AC_MASK |
6598                                                                 ID_MASK |
6599                                                                 NT_MASK |
6600                                                                 IF_MASK)
6601                                                                & 0xffff));
6602                      }
6603                  } else {
6604                      if (s->dflag) {
6605                          gen_helper_write_eflags(cpu_env, cpu_T[0],
6606                                             tcg_const_i32((TF_MASK | AC_MASK |
6607                                                            ID_MASK | NT_MASK)));
6608                      } else {
6609                          gen_helper_write_eflags(cpu_env, cpu_T[0],
6610                                             tcg_const_i32((TF_MASK | AC_MASK |
6611                                                            ID_MASK | NT_MASK)
6612                                                           & 0xffff));
6613                      }
6614                  }
6615              }
6616              gen_pop_update(s);
6617              set_cc_op(s, CC_OP_EFLAGS);
6618              /* abort translation because TF flag may change */
6619              gen_jmp_im(s->pc - s->cs_base);
6620              gen_eob(s);
6621          }
6622          break;
6623      case 0x9e: /* sahf */
6624          if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6625              goto illegal_op;
6626          gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
6627          gen_compute_eflags(s);
6628          tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6629          tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
6630          tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
6631          break;
6632      case 0x9f: /* lahf */
6633          if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6634              goto illegal_op;
6635          gen_compute_eflags(s);
6636          /* Note: gen_compute_eflags() only gives the condition codes */
6637          tcg_gen_ori_tl(cpu_T[0], cpu_cc_src, 0x02);
6638          gen_op_mov_reg_T0(OT_BYTE, R_AH);
6639          break;
6640      case 0xf5: /* cmc */
6641          gen_compute_eflags(s);
6642          tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6643          break;
6644      case 0xf8: /* clc */
6645          gen_compute_eflags(s);
6646          tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6647          break;
6648      case 0xf9: /* stc */
6649          gen_compute_eflags(s);
6650          tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6651          break;
6652      case 0xfc: /* cld */
6653          tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6654          tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6655          break;
6656      case 0xfd: /* std */
6657          tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6658          tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6659          break;
6660  
6661          /************************/
6662          /* bit operations */
6663      case 0x1ba: /* bt/bts/btr/btc Gv, im */
6664          ot = dflag + OT_WORD;
6665          modrm = cpu_ldub_code(env, s->pc++);
6666          op = (modrm >> 3) & 7;
6667          mod = (modrm >> 6) & 3;
6668          rm = (modrm & 7) | REX_B(s);
6669          if (mod != 3) {
6670              s->rip_offset = 1;
6671              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6672              gen_op_ld_T0_A0(ot + s->mem_index);
6673          } else {
6674              gen_op_mov_TN_reg(ot, 0, rm);
6675          }
6676          /* load shift */
6677          val = cpu_ldub_code(env, s->pc++);
6678          gen_op_movl_T1_im(val);
6679          if (op < 4)
6680              goto illegal_op;
6681          op -= 4;
6682          goto bt_op;
6683      case 0x1a3: /* bt Gv, Ev */
6684          op = 0;
6685          goto do_btx;
6686      case 0x1ab: /* bts */
6687          op = 1;
6688          goto do_btx;
6689      case 0x1b3: /* btr */
6690          op = 2;
6691          goto do_btx;
6692      case 0x1bb: /* btc */
6693          op = 3;
6694      do_btx:
6695          ot = dflag + OT_WORD;
6696          modrm = cpu_ldub_code(env, s->pc++);
6697          reg = ((modrm >> 3) & 7) | rex_r;
6698          mod = (modrm >> 6) & 3;
6699          rm = (modrm & 7) | REX_B(s);
6700          gen_op_mov_TN_reg(OT_LONG, 1, reg);
6701          if (mod != 3) {
6702              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6703              /* specific case: we need to add a displacement */
6704              gen_exts(ot, cpu_T[1]);
6705              tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
6706              tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6707              tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
6708              gen_op_ld_T0_A0(ot + s->mem_index);
6709          } else {
6710              gen_op_mov_TN_reg(ot, 0, rm);
6711          }
6712      bt_op:
6713          tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
6714          switch(op) {
6715          case 0:
6716              tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
6717              tcg_gen_movi_tl(cpu_cc_dst, 0);
6718              break;
6719          case 1:
6720              tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6721              tcg_gen_movi_tl(cpu_tmp0, 1);
6722              tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6723              tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6724              break;
6725          case 2:
6726              tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6727              tcg_gen_movi_tl(cpu_tmp0, 1);
6728              tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6729              tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6730              tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6731              break;
6732          default:
6733          case 3:
6734              tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6735              tcg_gen_movi_tl(cpu_tmp0, 1);
6736              tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6737              tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6738              break;
6739          }
6740          set_cc_op(s, CC_OP_SARB + ot);
6741          if (op != 0) {
6742              if (mod != 3)
6743                  gen_op_st_T0_A0(ot + s->mem_index);
6744              else
6745                  gen_op_mov_reg_T0(ot, rm);
6746              tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6747              tcg_gen_movi_tl(cpu_cc_dst, 0);
6748          }
6749          break;
6750      case 0x1bc: /* bsf */
6751      case 0x1bd: /* bsr */
6752          {
6753              int label1;
6754              TCGv t0;
6755  
6756              ot = dflag + OT_WORD;
6757              modrm = cpu_ldub_code(env, s->pc++);
6758              reg = ((modrm >> 3) & 7) | rex_r;
6759              gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6760              gen_extu(ot, cpu_T[0]);
6761              label1 = gen_new_label();
6762              tcg_gen_movi_tl(cpu_cc_dst, 0);
6763              t0 = tcg_temp_local_new();
6764              tcg_gen_mov_tl(t0, cpu_T[0]);
6765              tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
6766              if (b & 1) {
6767                  gen_helper_bsr(cpu_T[0], t0);
6768              } else {
6769                  gen_helper_bsf(cpu_T[0], t0);
6770              }
6771              gen_op_mov_reg_T0(ot, reg);
6772              tcg_gen_movi_tl(cpu_cc_dst, 1);
6773              gen_set_label(label1);
6774              set_cc_op(s, CC_OP_LOGICB + ot);
6775              tcg_temp_free(t0);
6776          }
6777          break;
6778          /************************/
6779          /* bcd */
6780      case 0x27: /* daa */
6781          if (CODE64(s))
6782              goto illegal_op;
6783          gen_update_cc_op(s);
6784          gen_helper_daa(cpu_env);
6785          set_cc_op(s, CC_OP_EFLAGS);
6786          break;
6787      case 0x2f: /* das */
6788          if (CODE64(s))
6789              goto illegal_op;
6790          gen_update_cc_op(s);
6791          gen_helper_das(cpu_env);
6792          set_cc_op(s, CC_OP_EFLAGS);
6793          break;
6794      case 0x37: /* aaa */
6795          if (CODE64(s))
6796              goto illegal_op;
6797          gen_update_cc_op(s);
6798          gen_helper_aaa(cpu_env);
6799          set_cc_op(s, CC_OP_EFLAGS);
6800          break;
6801      case 0x3f: /* aas */
6802          if (CODE64(s))
6803              goto illegal_op;
6804          gen_update_cc_op(s);
6805          gen_helper_aas(cpu_env);
6806          set_cc_op(s, CC_OP_EFLAGS);
6807          break;
6808      case 0xd4: /* aam */
6809          if (CODE64(s))
6810              goto illegal_op;
6811          val = cpu_ldub_code(env, s->pc++);
6812          if (val == 0) {
6813              gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6814          } else {
6815              gen_helper_aam(cpu_env, tcg_const_i32(val));
6816              set_cc_op(s, CC_OP_LOGICB);
6817          }
6818          break;
6819      case 0xd5: /* aad */
6820          if (CODE64(s))
6821              goto illegal_op;
6822          val = cpu_ldub_code(env, s->pc++);
6823          gen_helper_aad(cpu_env, tcg_const_i32(val));
6824          set_cc_op(s, CC_OP_LOGICB);
6825          break;
6826          /************************/
6827          /* misc */
6828      case 0x90: /* nop */
6829          /* XXX: xchg + rex handling */
6830          /* XXX: correct lock test for all insn */
6831          if (prefixes & PREFIX_LOCK) {
6832              goto illegal_op;
6833          }
6834          if (prefixes & PREFIX_REPZ) {
6835              gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
6836          }
6837          break;
6838      case 0x9b: /* fwait */
6839          if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6840              (HF_MP_MASK | HF_TS_MASK)) {
6841              gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6842          } else {
6843              gen_update_cc_op(s);
6844              gen_jmp_im(pc_start - s->cs_base);
6845              gen_helper_fwait(cpu_env);
6846          }
6847          break;
6848      case 0xcc: /* int3 */
6849          gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6850          break;
6851      case 0xcd: /* int N */
6852          val = cpu_ldub_code(env, s->pc++);
6853          if (s->vm86 && s->iopl != 3) {
6854              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6855          } else {
6856              gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6857          }
6858          break;
6859      case 0xce: /* into */
6860          if (CODE64(s))
6861              goto illegal_op;
6862          gen_update_cc_op(s);
6863          gen_jmp_im(pc_start - s->cs_base);
6864          gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
6865          break;
6866  #ifdef WANT_ICEBP
6867      case 0xf1: /* icebp (undocumented, exits to external debugger) */
6868          gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6869  #if 1
6870          gen_debug(s, pc_start - s->cs_base);
6871  #else
6872          /* start debug */
6873          tb_flush(cpu_single_env);
6874          qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6875  #endif
6876          break;
6877  #endif
6878      case 0xfa: /* cli */
6879          if (!s->vm86) {
6880              if (s->cpl <= s->iopl) {
6881                  gen_helper_cli(cpu_env);
6882              } else {
6883                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6884              }
6885          } else {
6886              if (s->iopl == 3) {
6887                  gen_helper_cli(cpu_env);
6888              } else {
6889                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6890              }
6891          }
6892          break;
6893      case 0xfb: /* sti */
6894          if (!s->vm86) {
6895              if (s->cpl <= s->iopl) {
6896              gen_sti:
6897                  gen_helper_sti(cpu_env);
6898                  /* interruptions are enabled only the first insn after sti */
6899                  /* If several instructions disable interrupts, only the
6900                     _first_ does it */
6901                  if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
6902                      gen_helper_set_inhibit_irq(cpu_env);
6903                  /* give a chance to handle pending irqs */
6904                  gen_jmp_im(s->pc - s->cs_base);
6905                  gen_eob(s);
6906              } else {
6907                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6908              }
6909          } else {
6910              if (s->iopl == 3) {
6911                  goto gen_sti;
6912              } else {
6913                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6914              }
6915          }
6916          break;
6917      case 0x62: /* bound */
6918          if (CODE64(s))
6919              goto illegal_op;
6920          ot = dflag ? OT_LONG : OT_WORD;
6921          modrm = cpu_ldub_code(cpu_single_env, s->pc++);
6922          reg = (modrm >> 3) & 7;
6923          mod = (modrm >> 6) & 3;
6924          if (mod == 3)
6925              goto illegal_op;
6926          gen_op_mov_TN_reg(ot, 0, reg);
6927          gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
6928          gen_jmp_im(pc_start - s->cs_base);
6929          tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6930          if (ot == OT_WORD) {
6931              gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
6932          } else {
6933              gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
6934          }
6935          break;
6936      case 0x1c8 ... 0x1cf: /* bswap reg */
6937          reg = (b & 7) | REX_B(s);
6938  #ifdef TARGET_X86_64
6939          if (dflag == 2) {
6940              gen_op_mov_TN_reg(OT_QUAD, 0, reg);
6941              tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
6942              gen_op_mov_reg_T0(OT_QUAD, reg);
6943          } else
6944  #endif
6945          {
6946              gen_op_mov_TN_reg(OT_LONG, 0, reg);
6947              tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
6948              tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
6949              gen_op_mov_reg_T0(OT_LONG, reg);
6950          }
6951          break;
6952      case 0xd6: /* salc */
6953          if (CODE64(s))
6954              goto illegal_op;
6955          gen_compute_eflags_c(s, cpu_T[0], false);
6956          tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
6957          gen_op_mov_reg_T0(OT_BYTE, R_EAX);
6958          break;
6959      case 0xe0: /* loopnz */
6960      case 0xe1: /* loopz */
6961      case 0xe2: /* loop */
6962      case 0xe3: /* jecxz */
6963          {
6964              int l1, l2, l3;
6965  
6966              tval = (int8_t)insn_get(env, s, OT_BYTE);
6967              next_eip = s->pc - s->cs_base;
6968              tval += next_eip;
6969              if (s->dflag == 0)
6970                  tval &= 0xffff;
6971  
6972              l1 = gen_new_label();
6973              l2 = gen_new_label();
6974              l3 = gen_new_label();
6975              b &= 3;
6976              switch(b) {
6977              case 0: /* loopnz */
6978              case 1: /* loopz */
6979                  gen_op_add_reg_im(s->aflag, R_ECX, -1);
6980                  gen_op_jz_ecx(s->aflag, l3);
6981                  gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
6982                  break;
6983              case 2: /* loop */
6984                  gen_op_add_reg_im(s->aflag, R_ECX, -1);
6985                  gen_op_jnz_ecx(s->aflag, l1);
6986                  break;
6987              default:
6988              case 3: /* jcxz */
6989                  gen_op_jz_ecx(s->aflag, l1);
6990                  break;
6991              }
6992  
6993              gen_set_label(l3);
6994              gen_jmp_im(next_eip);
6995              tcg_gen_br(l2);
6996  
6997              gen_set_label(l1);
6998              gen_jmp_im(tval);
6999              gen_set_label(l2);
7000              gen_eob(s);
7001          }
7002          break;
7003      case 0x130: /* wrmsr */
7004      case 0x132: /* rdmsr */
7005          if (s->cpl != 0) {
7006              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7007          } else {
7008              gen_update_cc_op(s);
7009              gen_jmp_im(pc_start - s->cs_base);
7010              if (b & 2) {
7011                  gen_helper_rdmsr(cpu_env);
7012              } else {
7013                  gen_helper_wrmsr(cpu_env);
7014              }
7015          }
7016          break;
7017      case 0x131: /* rdtsc */
7018          gen_update_cc_op(s);
7019          gen_jmp_im(pc_start - s->cs_base);
7020          if (use_icount)
7021              gen_io_start();
7022          gen_helper_rdtsc(cpu_env);
7023          if (use_icount) {
7024              gen_io_end();
7025              gen_jmp(s, s->pc - s->cs_base);
7026          }
7027          break;
7028      case 0x133: /* rdpmc */
7029          gen_update_cc_op(s);
7030          gen_jmp_im(pc_start - s->cs_base);
7031          gen_helper_rdpmc(cpu_env);
7032          break;
7033      case 0x134: /* sysenter */
7034          /* For Intel SYSENTER is valid on 64-bit */
7035          if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7036              goto illegal_op;
7037          if (!s->pe) {
7038              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7039          } else {
7040              gen_update_cc_op(s);
7041              gen_jmp_im(pc_start - s->cs_base);
7042              gen_helper_sysenter(cpu_env);
7043              gen_eob(s);
7044          }
7045          break;
7046      case 0x135: /* sysexit */
7047          /* For Intel SYSEXIT is valid on 64-bit */
7048          if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7049              goto illegal_op;
7050          if (!s->pe) {
7051              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7052          } else {
7053              gen_update_cc_op(s);
7054              gen_jmp_im(pc_start - s->cs_base);
7055              gen_helper_sysexit(cpu_env, tcg_const_i32(dflag));
7056              gen_eob(s);
7057          }
7058          break;
7059  #ifdef TARGET_X86_64
7060      case 0x105: /* syscall */
7061          /* XXX: is it usable in real mode ? */
7062          gen_update_cc_op(s);
7063          gen_jmp_im(pc_start - s->cs_base);
7064          gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7065          gen_eob(s);
7066          break;
7067      case 0x107: /* sysret */
7068          if (!s->pe) {
7069              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7070          } else {
7071              gen_update_cc_op(s);
7072              gen_jmp_im(pc_start - s->cs_base);
7073              gen_helper_sysret(cpu_env, tcg_const_i32(s->dflag));
7074              /* condition codes are modified only in long mode */
7075              if (s->lma)
7076                  set_cc_op(s, CC_OP_EFLAGS);
7077              gen_eob(s);
7078          }
7079          break;
7080  #endif
7081      case 0x1a2: /* cpuid */
7082          gen_update_cc_op(s);
7083          gen_jmp_im(pc_start - s->cs_base);
7084          gen_helper_cpuid(cpu_env);
7085          break;
7086      case 0xf4: /* hlt */
7087          if (s->cpl != 0) {
7088              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7089          } else {
7090              gen_update_cc_op(s);
7091              gen_jmp_im(pc_start - s->cs_base);
7092              gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7093              s->is_jmp = 3;
7094          }
7095          break;
7096      case 0x100:
7097          modrm = cpu_ldub_code(env, s->pc++);
7098          mod = (modrm >> 6) & 3;
7099          op = (modrm >> 3) & 7;
7100          switch(op) {
7101          case 0: /* sldt */
7102              if (!s->pe || s->vm86)
7103                  goto illegal_op;
7104              gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7105              tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
7106              ot = OT_WORD;
7107              if (mod == 3)
7108                  ot += s->dflag;
7109              gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7110              break;
7111          case 2: /* lldt */
7112              if (!s->pe || s->vm86)
7113                  goto illegal_op;
7114              if (s->cpl != 0) {
7115                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7116              } else {
7117                  gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7118                  gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7119                  gen_jmp_im(pc_start - s->cs_base);
7120                  tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7121                  gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7122              }
7123              break;
7124          case 1: /* str */
7125              if (!s->pe || s->vm86)
7126                  goto illegal_op;
7127              gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7128              tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
7129              ot = OT_WORD;
7130              if (mod == 3)
7131                  ot += s->dflag;
7132              gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7133              break;
7134          case 3: /* ltr */
7135              if (!s->pe || s->vm86)
7136                  goto illegal_op;
7137              if (s->cpl != 0) {
7138                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7139              } else {
7140                  gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7141                  gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7142                  gen_jmp_im(pc_start - s->cs_base);
7143                  tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7144                  gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7145              }
7146              break;
7147          case 4: /* verr */
7148          case 5: /* verw */
7149              if (!s->pe || s->vm86)
7150                  goto illegal_op;
7151              gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7152              gen_update_cc_op(s);
7153              if (op == 4) {
7154                  gen_helper_verr(cpu_env, cpu_T[0]);
7155              } else {
7156                  gen_helper_verw(cpu_env, cpu_T[0]);
7157              }
7158              set_cc_op(s, CC_OP_EFLAGS);
7159              break;
7160          default:
7161              goto illegal_op;
7162          }
7163          break;
7164      case 0x101:
7165          modrm = cpu_ldub_code(env, s->pc++);
7166          mod = (modrm >> 6) & 3;
7167          op = (modrm >> 3) & 7;
7168          rm = modrm & 7;
7169          switch(op) {
7170          case 0: /* sgdt */
7171              if (mod == 3)
7172                  goto illegal_op;
7173              gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7174              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7175              tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
7176              gen_op_st_T0_A0(OT_WORD + s->mem_index);
7177              gen_add_A0_im(s, 2);
7178              tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
7179              if (!s->dflag)
7180                  gen_op_andl_T0_im(0xffffff);
7181              gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7182              break;
7183          case 1:
7184              if (mod == 3) {
7185                  switch (rm) {
7186                  case 0: /* monitor */
7187                      if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7188                          s->cpl != 0)
7189                          goto illegal_op;
7190                      gen_update_cc_op(s);
7191                      gen_jmp_im(pc_start - s->cs_base);
7192  #ifdef TARGET_X86_64
7193                      if (s->aflag == 2) {
7194                          gen_op_movq_A0_reg(R_EAX);
7195                      } else
7196  #endif
7197                      {
7198                          gen_op_movl_A0_reg(R_EAX);
7199                          if (s->aflag == 0)
7200                              gen_op_andl_A0_ffff();
7201                      }
7202                      gen_add_A0_ds_seg(s);
7203                      gen_helper_monitor(cpu_env, cpu_A0);
7204                      break;
7205                  case 1: /* mwait */
7206                      if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7207                          s->cpl != 0)
7208                          goto illegal_op;
7209                      gen_update_cc_op(s);
7210                      gen_jmp_im(pc_start - s->cs_base);
7211                      gen_helper_mwait(cpu_env,
7212                                       tcg_const_i32(s->pc - pc_start));
7213                      gen_eob(s);
7214                      break;
7215                  default:
7216                      goto illegal_op;
7217                  }
7218              } else { /* sidt */
7219                  gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7220                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7221                  tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
7222                  gen_op_st_T0_A0(OT_WORD + s->mem_index);
7223                  gen_add_A0_im(s, 2);
7224                  tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
7225                  if (!s->dflag)
7226                      gen_op_andl_T0_im(0xffffff);
7227                  gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7228              }
7229              break;
7230          case 2: /* lgdt */
7231          case 3: /* lidt */
7232              if (mod == 3) {
7233                  gen_update_cc_op(s);
7234                  gen_jmp_im(pc_start - s->cs_base);
7235                  switch(rm) {
7236                  case 0: /* VMRUN */
7237                      if (!(s->flags & HF_SVME_MASK) || !s->pe)
7238                          goto illegal_op;
7239                      if (s->cpl != 0) {
7240                          gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7241                          break;
7242                      } else {
7243                          gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag),
7244                                           tcg_const_i32(s->pc - pc_start));
7245                          tcg_gen_exit_tb(0);
7246                          s->is_jmp = 3;
7247                      }
7248                      break;
7249                  case 1: /* VMMCALL */
7250                      if (!(s->flags & HF_SVME_MASK))
7251                          goto illegal_op;
7252                      gen_helper_vmmcall(cpu_env);
7253                      break;
7254                  case 2: /* VMLOAD */
7255                      if (!(s->flags & HF_SVME_MASK) || !s->pe)
7256                          goto illegal_op;
7257                      if (s->cpl != 0) {
7258                          gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7259                          break;
7260                      } else {
7261                          gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag));
7262                      }
7263                      break;
7264                  case 3: /* VMSAVE */
7265                      if (!(s->flags & HF_SVME_MASK) || !s->pe)
7266                          goto illegal_op;
7267                      if (s->cpl != 0) {
7268                          gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7269                          break;
7270                      } else {
7271                          gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag));
7272                      }
7273                      break;
7274                  case 4: /* STGI */
7275                      if ((!(s->flags & HF_SVME_MASK) &&
7276                           !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) ||
7277                          !s->pe)
7278                          goto illegal_op;
7279                      if (s->cpl != 0) {
7280                          gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7281                          break;
7282                      } else {
7283                          gen_helper_stgi(cpu_env);
7284                      }
7285                      break;
7286                  case 5: /* CLGI */
7287                      if (!(s->flags & HF_SVME_MASK) || !s->pe)
7288                          goto illegal_op;
7289                      if (s->cpl != 0) {
7290                          gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7291                          break;
7292                      } else {
7293                          gen_helper_clgi(cpu_env);
7294                      }
7295                      break;
7296                  case 6: /* SKINIT */
7297                      if ((!(s->flags & HF_SVME_MASK) &&
7298                           !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) ||
7299                          !s->pe)
7300                          goto illegal_op;
7301                      gen_helper_skinit(cpu_env);
7302                      break;
7303                  case 7: /* INVLPGA */
7304                      if (!(s->flags & HF_SVME_MASK) || !s->pe)
7305                          goto illegal_op;
7306                      if (s->cpl != 0) {
7307                          gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7308                          break;
7309                      } else {
7310                          gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag));
7311                      }
7312                      break;
7313                  default:
7314                      goto illegal_op;
7315                  }
7316              } else if (s->cpl != 0) {
7317                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7318              } else {
7319                  gen_svm_check_intercept(s, pc_start,
7320                                          op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE);
7321                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7322                  gen_op_ld_T1_A0(OT_WORD + s->mem_index);
7323                  gen_add_A0_im(s, 2);
7324                  gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
7325                  if (!s->dflag)
7326                      gen_op_andl_T0_im(0xffffff);
7327                  if (op == 2) {
7328                      tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
7329                      tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
7330                  } else {
7331                      tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
7332                      tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
7333                  }
7334              }
7335              break;
7336          case 4: /* smsw */
7337              gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7338  #if defined TARGET_X86_64 && defined WORDS_BIGENDIAN
7339              tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
7340  #else
7341              tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
7342  #endif
7343              gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 1);
7344              break;
7345          case 6: /* lmsw */
7346              if (s->cpl != 0) {
7347                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7348              } else {
7349                  gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7350                  gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7351                  gen_helper_lmsw(cpu_env, cpu_T[0]);
7352                  gen_jmp_im(s->pc - s->cs_base);
7353                  gen_eob(s);
7354              }
7355              break;
7356          case 7: /* invlpg */
7357              if (s->cpl != 0) {
7358                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7359              } else {
7360                  if (mod == 3) {
7361  #ifdef TARGET_X86_64
7362                      if (CODE64(s) && rm == 0) {
7363                          /* swapgs */
7364                          tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
7365                          tcg_gen_ld_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,kernelgsbase));
7366                          tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
7367                          tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,kernelgsbase));
7368                      } else
7369  #endif
7370                      {
7371                          goto illegal_op;
7372                      }
7373                  } else {
7374                      gen_update_cc_op(s);
7375                      gen_jmp_im(pc_start - s->cs_base);
7376                      gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7377                      gen_helper_invlpg(cpu_env, cpu_A0);
7378                      gen_jmp_im(s->pc - s->cs_base);
7379                      gen_eob(s);
7380                  }
7381              }
7382              break;
7383          default:
7384              goto illegal_op;
7385          }
7386          break;
7387      case 0x108: /* invd */
7388      case 0x109: /* wbinvd */
7389          if (s->cpl != 0) {
7390              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7391          } else {
7392              gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7393              /* nothing to do */
7394          }
7395          break;
7396      case 0x63: /* arpl or movslS (x86_64) */
7397  #ifdef TARGET_X86_64
7398          if (CODE64(s)) {
7399              int d_ot;
7400              /* d_ot is the size of destination */
7401              d_ot = dflag + OT_WORD;
7402  
7403              modrm = cpu_ldub_code(env, s->pc++);
7404              reg = ((modrm >> 3) & 7) | rex_r;
7405              mod = (modrm >> 6) & 3;
7406              rm = (modrm & 7) | REX_B(s);
7407  
7408              if (mod == 3) {
7409                  gen_op_mov_TN_reg(OT_LONG, 0, rm);
7410                  /* sign extend */
7411                  if (d_ot == OT_QUAD)
7412                      tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
7413                  gen_op_mov_reg_T0(d_ot, reg);
7414              } else {
7415                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7416                  if (d_ot == OT_QUAD) {
7417                      gen_op_lds_T0_A0(OT_LONG + s->mem_index);
7418                  } else {
7419                      gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7420                  }
7421                  gen_op_mov_reg_T0(d_ot, reg);
7422              }
7423          } else
7424  #endif
7425          {
7426              int label1;
7427              TCGv t0, t1, t2;
7428  
7429              if (!s->pe || s->vm86)
7430                  goto illegal_op;
7431              t0 = tcg_temp_local_new();
7432              t1 = tcg_temp_local_new();
7433              t2 = tcg_temp_local_new();
7434              ot = OT_WORD;
7435              modrm = cpu_ldub_code(env,  s->pc++);
7436              reg = (modrm >> 3) & 7;
7437              mod = (modrm >> 6) & 3;
7438              rm = modrm & 7;
7439              if (mod != 3) {
7440                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7441                  gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
7442              } else {
7443                  gen_op_mov_v_reg(ot, t0, rm);
7444              }
7445              gen_op_mov_v_reg(ot, t1, reg);
7446              tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7447              tcg_gen_andi_tl(t1, t1, 3);
7448              tcg_gen_movi_tl(t2, 0);
7449              label1 = gen_new_label();
7450              tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7451              tcg_gen_andi_tl(t0, t0, ~3);
7452              tcg_gen_or_tl(t0, t0, t1);
7453              tcg_gen_movi_tl(t2, CC_Z);
7454              gen_set_label(label1);
7455              if (mod != 3) {
7456                  gen_op_st_v(ot + s->mem_index, t0, cpu_A0);
7457              } else {
7458                  gen_op_mov_reg_v(ot, rm, t0);
7459              }
7460              gen_compute_eflags(s);
7461              tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7462              tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7463              tcg_temp_free(t0);
7464              tcg_temp_free(t1);
7465              tcg_temp_free(t2);
7466          }
7467          break;
7468      case 0x102: /* lar */
7469      case 0x103: /* lsl */
7470          {
7471              int label1;
7472              TCGv t0;
7473              if (!s->pe || s->vm86)
7474                  goto illegal_op;
7475              ot = dflag ? OT_LONG : OT_WORD;
7476              modrm = cpu_ldub_code(env,  s->pc++);
7477              reg = ((modrm >> 3) & 7) | rex_r;
7478              gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0);
7479              t0 = tcg_temp_local_new();
7480              gen_update_cc_op(s);
7481              if (b == 0x102) {
7482                  gen_helper_lar(t0, cpu_env, cpu_T[0]);
7483              } else {
7484                  gen_helper_lsl(t0, cpu_env, cpu_T[0]);
7485              }
7486              tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7487              label1 = gen_new_label();
7488              tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7489              gen_op_mov_reg_v(ot, reg, t0);
7490              gen_set_label(label1);
7491              set_cc_op(s, CC_OP_EFLAGS);
7492              tcg_temp_free(t0);
7493          }
7494          break;
7495      case 0x118:
7496          modrm = cpu_ldub_code(env, s->pc++);
7497          mod = (modrm >> 6) & 3;
7498          op = (modrm >> 3) & 7;
7499          switch(op) {
7500          case 0: /* prefetchnta */
7501          case 1: /* prefetchnt0 */
7502          case 2: /* prefetchnt0 */
7503          case 3: /* prefetchnt0 */
7504              if (mod == 3)
7505                  goto illegal_op;
7506              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7507              /* nothing more to do */
7508              break;
7509          default: /* nop (multi byte) */
7510              gen_nop_modrm(env, s, modrm);
7511              break;
7512          }
7513          break;
7514      case 0x119 ... 0x11f: /* nop (multi byte) */
7515          modrm = cpu_ldub_code(env, s->pc++);
7516          gen_nop_modrm(env, s, modrm);
7517          break;
7518      case 0x120: /* mov reg, crN */
7519      case 0x122: /* mov crN, reg */
7520          if (s->cpl != 0) {
7521              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7522          } else {
7523              modrm = cpu_ldub_code(env, s->pc++);
7524              if ((modrm & 0xc0) != 0xc0)
7525                  goto illegal_op;
7526              rm = (modrm & 7) | REX_B(s);
7527              reg = ((modrm >> 3) & 7) | rex_r;
7528              if (CODE64(s))
7529                  ot = OT_QUAD;
7530              else
7531                  ot = OT_LONG;
7532              switch(reg) {
7533              case 0:
7534              case 2:
7535              case 3:
7536              case 4:
7537              case 8:
7538                  gen_update_cc_op(s);
7539                  gen_jmp_im(pc_start - s->cs_base);
7540                  if (b & 2) {
7541                      gen_op_mov_TN_reg(ot, 0, rm);
7542                      gen_helper_write_crN(cpu_env, tcg_const_i32(reg), cpu_T[0]);
7543                      gen_jmp_im(s->pc - s->cs_base);
7544                      gen_eob(s);
7545                  } else {
7546                      gen_helper_read_crN(cpu_T[0], cpu_env, tcg_const_i32(reg));
7547                      gen_op_mov_reg_T0(ot, rm);
7548                  }
7549                  break;
7550              default:
7551                  goto illegal_op;
7552              }
7553          }
7554          break;
7555      case 0x121: /* mov reg, drN */
7556      case 0x123: /* mov drN, reg */
7557          if (s->cpl != 0) {
7558              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7559          } else {
7560              modrm = cpu_ldub_code(env, s->pc++);
7561              if ((modrm & 0xc0) != 0xc0)
7562                  goto illegal_op;
7563              rm = (modrm & 7) | REX_B(s);
7564              reg = ((modrm >> 3) & 7) | rex_r;
7565              if (CODE64(s))
7566                  ot = OT_QUAD;
7567              else
7568                  ot = OT_LONG;
7569              /* XXX: do it dynamically with CR4.DE bit */
7570              if (reg == 4 || reg == 5 || reg >= 8)
7571                  goto illegal_op;
7572              if (b & 2) {
7573                  gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7574                  gen_op_mov_TN_reg(ot, 0, rm);
7575                  gen_helper_movl_drN_T0(cpu_env, tcg_const_i32(reg), cpu_T[0]);
7576                  gen_jmp_im(s->pc - s->cs_base);
7577                  gen_eob(s);
7578              } else {
7579                  gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7580                  tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
7581                  gen_op_mov_reg_T0(ot, rm);
7582              }
7583          }
7584          break;
7585      case 0x106: /* clts */
7586          if (s->cpl != 0) {
7587              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7588          } else {
7589              gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7590              gen_helper_clts(cpu_env);
7591              /* abort block because static cpu state changed */
7592              gen_jmp_im(s->pc - s->cs_base);
7593              gen_eob(s);
7594          }
7595          break;
7596      /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7597      case 0x1c3: /* MOVNTI reg, mem */
7598          if (!(s->cpuid_features & CPUID_SSE2))
7599              goto illegal_op;
7600          ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
7601          modrm = cpu_ldub_code(env, s->pc++);
7602          mod = (modrm >> 6) & 3;
7603          if (mod == 3)
7604              goto illegal_op;
7605          reg = ((modrm >> 3) & 7) | rex_r;
7606          /* generate a generic store */
7607          gen_ldst_modrm(env, s, modrm, ot, reg, 1);
7608          break;
7609      case 0x1ae:
7610          modrm = cpu_ldub_code(env, s->pc++);
7611          mod = (modrm >> 6) & 3;
7612          op = (modrm >> 3) & 7;
7613          switch(op) {
7614          case 0: /* fxsave */
7615              if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7616                  (s->flags & HF_EM_MASK))
7617                  goto illegal_op;
7618              if (s->flags & HF_TS_MASK) {
7619                  gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7620                  break;
7621              }
7622              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7623              gen_update_cc_op(s);
7624              gen_jmp_im(pc_start - s->cs_base);
7625              gen_helper_fxsave(cpu_env, cpu_A0, tcg_const_i32((s->dflag == 2)));
7626              break;
7627          case 1: /* fxrstor */
7628              if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7629                  (s->flags & HF_EM_MASK))
7630                  goto illegal_op;
7631              if (s->flags & HF_TS_MASK) {
7632                  gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7633                  break;
7634              }
7635              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7636              gen_update_cc_op(s);
7637              gen_jmp_im(pc_start - s->cs_base);
7638              gen_helper_fxrstor(cpu_env, cpu_A0, tcg_const_i32((s->dflag == 2)));
7639              break;
7640          case 2: /* ldmxcsr */
7641          case 3: /* stmxcsr */
7642              if (s->flags & HF_TS_MASK) {
7643                  gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7644                  break;
7645              }
7646              if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
7647                  mod == 3)
7648                  goto illegal_op;
7649              gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7650              if (op == 2) {
7651                  gen_op_ld_T0_A0(OT_LONG + s->mem_index);
7652                  tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7653              } else {
7654                  tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7655                  gen_op_st_T0_A0(OT_LONG + s->mem_index);
7656              }
7657              break;
7658          case 5: /* lfence */
7659          case 6: /* mfence */
7660              if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
7661                  goto illegal_op;
7662              break;
7663          case 7: /* sfence / clflush */
7664              if ((modrm & 0xc7) == 0xc0) {
7665                  /* sfence */
7666                  /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7667                  if (!(s->cpuid_features & CPUID_SSE))
7668                      goto illegal_op;
7669              } else {
7670                  /* clflush */
7671                  if (!(s->cpuid_features & CPUID_CLFLUSH))
7672                      goto illegal_op;
7673                  gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7674              }
7675              break;
7676          default:
7677              goto illegal_op;
7678          }
7679          break;
7680      case 0x10d: /* 3DNow! prefetch(w) */
7681          modrm = cpu_ldub_code(env, s->pc++);
7682          mod = (modrm >> 6) & 3;
7683          if (mod == 3)
7684              goto illegal_op;
7685          gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
7686          /* ignore for now */
7687          break;
7688      case 0x1aa: /* rsm */
7689          gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
7690          if (!(s->flags & HF_SMM_MASK))
7691              goto illegal_op;
7692          gen_update_cc_op(s);
7693          gen_jmp_im(s->pc - s->cs_base);
7694          gen_helper_rsm(cpu_env);
7695          gen_eob(s);
7696          break;
7697      case 0x1b8: /* SSE4.2 popcnt */
7698          if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
7699               PREFIX_REPZ)
7700              goto illegal_op;
7701          if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
7702              goto illegal_op;
7703  
7704          modrm = cpu_ldub_code(env, s->pc++);
7705          reg = ((modrm >> 3) & 7);
7706  
7707          if (s->prefix & PREFIX_DATA)
7708              ot = OT_WORD;
7709          else if (s->dflag != 2)
7710              ot = OT_LONG;
7711          else
7712              ot = OT_QUAD;
7713  
7714          gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
7715          gen_helper_popcnt(cpu_T[0], cpu_env, cpu_T[0], tcg_const_i32(ot));
7716          gen_op_mov_reg_T0(ot, reg);
7717  
7718          set_cc_op(s, CC_OP_EFLAGS);
7719          break;
7720      case 0x10e ... 0x10f:
7721          /* 3DNow! instructions, ignore prefixes */
7722          s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
7723      case 0x110 ... 0x117:
7724      case 0x128 ... 0x12f:
7725      case 0x138 ... 0x13a:
7726      case 0x150 ... 0x177:
7727      case 0x17c ... 0x17f:
7728      case 0x1c2:
7729      case 0x1c4 ... 0x1c6:
7730      case 0x1d0 ... 0x1fe:
7731          gen_sse(env, s, b, pc_start, rex_r);
7732          break;
7733      default:
7734          goto illegal_op;
7735      }
7736      /* lock generation */
7737      if (s->prefix & PREFIX_LOCK)
7738          gen_helper_unlock();
7739      return s->pc;
7740   illegal_op:
7741      if (s->prefix & PREFIX_LOCK)
7742          gen_helper_unlock();
7743      /* XXX: ensure that no lock was generated */
7744      gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
7745      return s->pc;
7746  }
7747  
optimize_flags_init(void)7748  void optimize_flags_init(void)
7749  {
7750  #if TCG_TARGET_REG_BITS == 32
7751      assert(sizeof(CCTable) == (1 << 3));
7752  #else
7753      assert(sizeof(CCTable) == (1 << 4));
7754  #endif
7755      cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7756      cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
7757                                         offsetof(CPUX86State, cc_op), "cc_op");
7758      cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src),
7759                                      "cc_src");
7760      cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
7761                                      "cc_dst");
7762  }
7763  
7764  /* generate intermediate code in tcg_ctx.gen_opc_buf and gen_opparam_buf for
7765     basic block 'tb'. If search_pc is TRUE, also generate PC
7766     information for each intermediate instruction. */
gen_intermediate_code_internal(CPUX86State * env,TranslationBlock * tb,int search_pc)7767  static inline void gen_intermediate_code_internal(CPUX86State *env,
7768                                                    TranslationBlock *tb,
7769                                                    int search_pc)
7770  {
7771      DisasContext dc1, *dc = &dc1;
7772      target_ulong pc_ptr;
7773      uint16_t *gen_opc_end;
7774      CPUBreakpoint *bp;
7775      int j, lj;
7776      uint64_t flags;
7777      target_ulong pc_start;
7778      target_ulong cs_base;
7779      int num_insns;
7780      int max_insns;
7781  
7782      /* generate intermediate code */
7783      pc_start = tb->pc;
7784      cs_base = tb->cs_base;
7785      flags = tb->flags;
7786  
7787      dc->pe = (flags >> HF_PE_SHIFT) & 1;
7788      dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
7789      dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
7790      dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
7791      dc->f_st = 0;
7792      dc->vm86 = (flags >> VM_SHIFT) & 1;
7793      dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
7794      dc->iopl = (flags >> IOPL_SHIFT) & 3;
7795      dc->tf = (flags >> TF_SHIFT) & 1;
7796      dc->singlestep_enabled = ENV_GET_CPU(env)->singlestep_enabled;
7797      dc->cc_op = CC_OP_DYNAMIC;
7798      dc->cc_op_dirty = false;
7799      dc->cs_base = cs_base;
7800      dc->tb = tb;
7801      dc->popl_esp_hack = 0;
7802      /* select memory access functions */
7803      dc->mem_index = 0;
7804      if (flags & HF_SOFTMMU_MASK) {
7805          if (dc->cpl == 3)
7806              dc->mem_index = 2 * 4;
7807          else
7808              dc->mem_index = 1 * 4;
7809      }
7810      dc->cpuid_features = env->cpuid_features;
7811      dc->cpuid_ext_features = env->cpuid_ext_features;
7812      dc->cpuid_ext2_features = env->cpuid_ext2_features;
7813      dc->cpuid_ext3_features = env->cpuid_ext3_features;
7814  #ifdef TARGET_X86_64
7815      dc->lma = (flags >> HF_LMA_SHIFT) & 1;
7816      dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
7817  #endif
7818      dc->flags = flags;
7819      dc->jmp_opt = !(dc->tf || ENV_GET_CPU(env)->singlestep_enabled ||
7820                      (flags & HF_INHIBIT_IRQ_MASK)
7821  #ifndef CONFIG_SOFTMMU
7822                      || (flags & HF_SOFTMMU_MASK)
7823  #endif
7824                      );
7825  #if 0
7826      /* check addseg logic */
7827      if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
7828          printf("ERROR addseg\n");
7829  #endif
7830  
7831      cpu_T[0] = tcg_temp_new();
7832      cpu_T[1] = tcg_temp_new();
7833      cpu_A0 = tcg_temp_new();
7834      cpu_T3 = tcg_temp_new();
7835  
7836      cpu_tmp0 = tcg_temp_new();
7837      cpu_tmp1_i64 = tcg_temp_new_i64();
7838      cpu_tmp2_i32 = tcg_temp_new_i32();
7839      cpu_tmp3_i32 = tcg_temp_new_i32();
7840      cpu_tmp4 = tcg_temp_new();
7841      cpu_tmp5 = tcg_temp_new();
7842      cpu_tmp6 = tcg_temp_new();
7843      cpu_ptr0 = tcg_temp_new_ptr();
7844      cpu_ptr1 = tcg_temp_new_ptr();
7845  
7846      gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
7847  
7848      dc->is_jmp = DISAS_NEXT;
7849      pc_ptr = pc_start;
7850      lj = -1;
7851      num_insns = 0;
7852      max_insns = tb->cflags & CF_COUNT_MASK;
7853      if (max_insns == 0)
7854          max_insns = CF_COUNT_MASK;
7855  
7856      gen_icount_start();
7857      for(;;) {
7858          if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
7859              QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
7860                  if (bp->pc == pc_ptr &&
7861                      !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
7862                      gen_debug(dc, pc_ptr - dc->cs_base);
7863                      break;
7864                  }
7865              }
7866          }
7867          if (search_pc) {
7868              j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
7869              if (lj < j) {
7870                  lj++;
7871                  while (lj < j)
7872                      tcg_ctx.gen_opc_instr_start[lj++] = 0;
7873              }
7874              tcg_ctx.gen_opc_pc[lj] = pc_ptr;
7875              gen_opc_cc_op[lj] = dc->cc_op;
7876              tcg_ctx.gen_opc_instr_start[lj] = 1;
7877              tcg_ctx.gen_opc_icount[lj] = num_insns;
7878          }
7879          if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
7880              gen_io_start();
7881  
7882          pc_ptr = disas_insn(env, dc, pc_ptr);
7883          num_insns++;
7884  #ifdef CONFIG_HAX
7885          if (hax_enabled() && hax_stop_translate(ENV_GET_CPU(env)))
7886          {
7887              gen_jmp_im(pc_ptr - dc->cs_base);
7888              gen_eob(dc);
7889              break;
7890          }
7891  #endif
7892          /* stop translation if indicated */
7893          if (dc->is_jmp)
7894              break;
7895          /* if single step mode, we generate only one instruction and
7896             generate an exception */
7897          /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7898             the flag and abort the translation to give the irqs a
7899             change to be happen */
7900          if (dc->tf || dc->singlestep_enabled ||
7901              (flags & HF_INHIBIT_IRQ_MASK)) {
7902              gen_jmp_im(pc_ptr - dc->cs_base);
7903              gen_eob(dc);
7904              break;
7905          }
7906          /* if too long translation, stop generation too */
7907          if (tcg_ctx.gen_opc_ptr >= gen_opc_end ||
7908              (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
7909              num_insns >= max_insns) {
7910              gen_jmp_im(pc_ptr - dc->cs_base);
7911              gen_eob(dc);
7912              break;
7913          }
7914          if (singlestep) {
7915              gen_jmp_im(pc_ptr - dc->cs_base);
7916              gen_eob(dc);
7917              break;
7918          }
7919      }
7920      if (tb->cflags & CF_LAST_IO)
7921          gen_io_end();
7922      gen_icount_end(tb, num_insns);
7923      *tcg_ctx.gen_opc_ptr = INDEX_op_end;
7924      /* we don't forget to fill the last values */
7925      if (search_pc) {
7926          j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
7927          lj++;
7928          while (lj <= j)
7929              tcg_ctx.gen_opc_instr_start[lj++] = 0;
7930      }
7931  
7932  #ifdef DEBUG_DISAS
7933      log_cpu_state_mask(CPU_LOG_TB_CPU, ENV_GET_CPU(env), X86_DUMP_CCOP);
7934      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
7935          int disas_flags;
7936          qemu_log("----------------\n");
7937          qemu_log("IN: %s\n", lookup_symbol(pc_start));
7938  #ifdef TARGET_X86_64
7939          if (dc->code64)
7940              disas_flags = 2;
7941          else
7942  #endif
7943              disas_flags = !dc->code32;
7944          log_target_disas(env, pc_start, pc_ptr - pc_start, disas_flags);
7945          qemu_log("\n");
7946      }
7947  #endif
7948  
7949      if (!search_pc) {
7950          tb->size = pc_ptr - pc_start;
7951          tb->icount = num_insns;
7952      }
7953  }
7954  
gen_intermediate_code(CPUX86State * env,TranslationBlock * tb)7955  void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
7956  {
7957      gen_intermediate_code_internal(env, tb, 0);
7958  }
7959  
gen_intermediate_code_pc(CPUX86State * env,TranslationBlock * tb)7960  void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb)
7961  {
7962      gen_intermediate_code_internal(env, tb, 1);
7963  }
7964  
restore_state_to_opc(CPUX86State * env,TranslationBlock * tb,int pc_pos)7965  void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
7966  {
7967      int cc_op;
7968  #ifdef DEBUG_DISAS
7969      if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
7970          int i;
7971          qemu_log("RESTORE:\n");
7972          for(i = 0;i <= pc_pos; i++) {
7973              if (tcg_ctx.gen_opc_instr_start[i]) {
7974                  qemu_log("0x%04x: " TARGET_FMT_lx "\n", i,
7975                          tcg_ctx.gen_opc_pc[i]);
7976              }
7977          }
7978          qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
7979                  pc_pos, tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base,
7980                  (uint32_t)tb->cs_base);
7981      }
7982  #endif
7983      env->eip = tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base;
7984      cc_op = gen_opc_cc_op[pc_pos];
7985      if (cc_op != CC_OP_DYNAMIC)
7986          env->cc_op = cc_op;
7987  }
7988