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