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