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