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