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