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