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