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