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