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