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