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