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 void gen_sty_env_A0(DisasContext *s, int offset, bool align) 2939 { 2940 int mem_index = s->mem_index; 2941 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(0))); 2942 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, 2943 MO_LEUQ | (align ? MO_ALIGN_32 : 0)); 2944 tcg_gen_addi_tl(s->tmp0, s->A0, 8); 2945 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(1))); 2946 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2947 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2948 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(2))); 2949 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2950 tcg_gen_addi_tl(s->tmp0, s->A0, 24); 2951 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(3))); 2952 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2953 } 2954 2955 static inline void gen_op_movo(DisasContext *s, int d_offset, int s_offset) 2956 { 2957 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, s_offset + offsetof(XMMReg, XMM_Q(0))); 2958 tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset + offsetof(XMMReg, XMM_Q(0))); 2959 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, s_offset + offsetof(XMMReg, XMM_Q(1))); 2960 tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset + offsetof(XMMReg, XMM_Q(1))); 2961 } 2962 2963 static inline void gen_op_movq(DisasContext *s, int d_offset, int s_offset) 2964 { 2965 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, s_offset); 2966 tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset); 2967 } 2968 2969 static inline void gen_op_movl(DisasContext *s, int d_offset, int s_offset) 2970 { 2971 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, s_offset); 2972 tcg_gen_st_i32(s->tmp2_i32, cpu_env, d_offset); 2973 } 2974 2975 static inline void gen_op_movq_env_0(DisasContext *s, int d_offset) 2976 { 2977 tcg_gen_movi_i64(s->tmp1_i64, 0); 2978 tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset); 2979 } 2980 2981 #define ZMM_OFFSET(reg) offsetof(CPUX86State, xmm_regs[reg]) 2982 #define XMM_OFFSET(reg) offsetof(CPUX86State, xmm_regs[reg].ZMM_X(0)) 2983 2984 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg); 2985 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg); 2986 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val); 2987 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val); 2988 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b); 2989 typedef void (*SSEFunc_0_eppp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, 2990 TCGv_ptr reg_c); 2991 typedef void (*SSEFunc_0_epppp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, 2992 TCGv_ptr reg_c, TCGv_ptr reg_d); 2993 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, 2994 TCGv_i32 val); 2995 typedef void (*SSEFunc_0_epppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, 2996 TCGv_ptr reg_c, TCGv_i32 val); 2997 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val); 2998 typedef void (*SSEFunc_0_pppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_ptr reg_c, 2999 TCGv_i32 val); 3000 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, 3001 TCGv val); 3002 typedef void (*SSEFunc_0_epppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, 3003 TCGv_ptr reg_c, TCGv val); 3004 3005 static bool first = true; static unsigned long limit; 3006 #include "decode-new.h" 3007 #include "emit.c.inc" 3008 #include "decode-new.c.inc" 3009 3010 #define SSE_OPF_V0 (1 << 0) /* vex.v must be 1111b (only 2 operands) */ 3011 #define SSE_OPF_CMP (1 << 1) /* does not write for first operand */ 3012 #define SSE_OPF_BLENDV (1 << 2) /* blendv* instruction */ 3013 #define SSE_OPF_SPECIAL (1 << 3) /* magic */ 3014 #define SSE_OPF_3DNOW (1 << 4) /* 3DNow! instruction */ 3015 #define SSE_OPF_MMX (1 << 5) /* MMX/integer/AVX2 instruction */ 3016 #define SSE_OPF_SCALAR (1 << 6) /* Has SSE scalar variants */ 3017 #define SSE_OPF_SHUF (1 << 9) /* pshufx/shufpx */ 3018 3019 #define OP(op, flags, a, b, c, d) \ 3020 {flags, {{.op = a}, {.op = b}, {.op = c}, {.op = d} } } 3021 3022 #define MMX_OP(x) OP(op2, SSE_OPF_MMX, \ 3023 gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm, NULL, NULL) 3024 3025 #define SSE_FOP(name) OP(op2, SSE_OPF_SCALAR, \ 3026 gen_helper_##name##ps##_xmm, gen_helper_##name##pd##_xmm, \ 3027 gen_helper_##name##ss, gen_helper_##name##sd) 3028 #define SSE_OP(sname, dname, op, flags) OP(op, flags, \ 3029 gen_helper_##sname##_xmm, gen_helper_##dname##_xmm, NULL, NULL) 3030 3031 #define SSE_OP_UNARY(a, b, c, d) \ 3032 {SSE_OPF_SCALAR | SSE_OPF_V0, {{.op1 = a}, {.op1 = b}, {.op2 = c}, {.op2 = d} } } 3033 3034 typedef union SSEFuncs { 3035 SSEFunc_0_epp op1; 3036 SSEFunc_0_ppi op1i; 3037 SSEFunc_0_eppt op1t; 3038 SSEFunc_0_eppp op2; 3039 SSEFunc_0_pppi op2i; 3040 SSEFunc_0_epppp op3; 3041 } SSEFuncs; 3042 3043 struct SSEOpHelper_table1 { 3044 int flags; 3045 SSEFuncs fn[4]; 3046 }; 3047 3048 #define SSE_3DNOW { SSE_OPF_3DNOW } 3049 #define SSE_SPECIAL { SSE_OPF_SPECIAL } 3050 3051 static const struct SSEOpHelper_table1 sse_op_table1[256] = { 3052 /* 3DNow! extensions */ 3053 [0x0e] = SSE_SPECIAL, /* femms */ 3054 [0x0f] = SSE_3DNOW, /* pf... (sse_op_table5) */ 3055 /* pure SSE operations */ 3056 [0x10] = SSE_SPECIAL, /* movups, movupd, movss, movsd */ 3057 [0x11] = SSE_SPECIAL, /* movups, movupd, movss, movsd */ 3058 [0x12] = SSE_SPECIAL, /* movlps, movlpd, movsldup, movddup */ 3059 [0x13] = SSE_SPECIAL, /* movlps, movlpd */ 3060 [0x14] = SSE_OP(punpckldq, punpcklqdq, op2, 0), /* unpcklps, unpcklpd */ 3061 [0x15] = SSE_OP(punpckhdq, punpckhqdq, op2, 0), /* unpckhps, unpckhpd */ 3062 [0x16] = SSE_SPECIAL, /* movhps, movhpd, movshdup */ 3063 [0x17] = SSE_SPECIAL, /* movhps, movhpd */ 3064 3065 [0x28] = SSE_SPECIAL, /* movaps, movapd */ 3066 [0x29] = SSE_SPECIAL, /* movaps, movapd */ 3067 [0x2a] = SSE_SPECIAL, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */ 3068 [0x2b] = SSE_SPECIAL, /* movntps, movntpd, movntss, movntsd */ 3069 [0x2c] = SSE_SPECIAL, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */ 3070 [0x2d] = SSE_SPECIAL, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */ 3071 [0x2e] = OP(op1, SSE_OPF_CMP | SSE_OPF_SCALAR | SSE_OPF_V0, 3072 gen_helper_ucomiss, gen_helper_ucomisd, NULL, NULL), 3073 [0x2f] = OP(op1, SSE_OPF_CMP | SSE_OPF_SCALAR | SSE_OPF_V0, 3074 gen_helper_comiss, gen_helper_comisd, NULL, NULL), 3075 [0x50] = SSE_SPECIAL, /* movmskps, movmskpd */ 3076 [0x51] = SSE_OP_UNARY( 3077 gen_helper_sqrtps_xmm, gen_helper_sqrtpd_xmm, 3078 gen_helper_sqrtss, gen_helper_sqrtsd), 3079 [0x52] = SSE_OP_UNARY( 3080 gen_helper_rsqrtps_xmm, NULL, gen_helper_rsqrtss, NULL), 3081 [0x53] = SSE_OP_UNARY( 3082 gen_helper_rcpps_xmm, NULL, gen_helper_rcpss, NULL), 3083 [0x54] = SSE_OP(pand, pand, op2, 0), /* andps, andpd */ 3084 [0x55] = SSE_OP(pandn, pandn, op2, 0), /* andnps, andnpd */ 3085 [0x56] = SSE_OP(por, por, op2, 0), /* orps, orpd */ 3086 [0x57] = SSE_OP(pxor, pxor, op2, 0), /* xorps, xorpd */ 3087 [0x58] = SSE_FOP(add), 3088 [0x59] = SSE_FOP(mul), 3089 [0x5a] = SSE_OP_UNARY( 3090 gen_helper_cvtps2pd_xmm, gen_helper_cvtpd2ps_xmm, 3091 gen_helper_cvtss2sd, gen_helper_cvtsd2ss), 3092 [0x5b] = OP(op1, SSE_OPF_V0, 3093 gen_helper_cvtdq2ps_xmm, gen_helper_cvtps2dq_xmm, 3094 gen_helper_cvttps2dq_xmm, NULL), 3095 [0x5c] = SSE_FOP(sub), 3096 [0x5d] = SSE_FOP(min), 3097 [0x5e] = SSE_FOP(div), 3098 [0x5f] = SSE_FOP(max), 3099 3100 [0xc2] = SSE_FOP(cmpeq), /* sse_op_table4 */ 3101 [0xc6] = SSE_OP(shufps, shufpd, op2i, SSE_OPF_SHUF), 3102 3103 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */ 3104 [0x38] = SSE_SPECIAL, 3105 [0x3a] = SSE_SPECIAL, 3106 3107 /* MMX ops and their SSE extensions */ 3108 [0x60] = MMX_OP(punpcklbw), 3109 [0x61] = MMX_OP(punpcklwd), 3110 [0x62] = MMX_OP(punpckldq), 3111 [0x63] = MMX_OP(packsswb), 3112 [0x64] = MMX_OP(pcmpgtb), 3113 [0x65] = MMX_OP(pcmpgtw), 3114 [0x66] = MMX_OP(pcmpgtl), 3115 [0x67] = MMX_OP(packuswb), 3116 [0x68] = MMX_OP(punpckhbw), 3117 [0x69] = MMX_OP(punpckhwd), 3118 [0x6a] = MMX_OP(punpckhdq), 3119 [0x6b] = MMX_OP(packssdw), 3120 [0x6c] = OP(op2, SSE_OPF_MMX, 3121 NULL, gen_helper_punpcklqdq_xmm, NULL, NULL), 3122 [0x6d] = OP(op2, SSE_OPF_MMX, 3123 NULL, gen_helper_punpckhqdq_xmm, NULL, NULL), 3124 [0x6e] = SSE_SPECIAL, /* movd mm, ea */ 3125 [0x6f] = SSE_SPECIAL, /* movq, movdqa, , movqdu */ 3126 [0x70] = OP(op1i, SSE_OPF_SHUF | SSE_OPF_MMX | SSE_OPF_V0, 3127 gen_helper_pshufw_mmx, gen_helper_pshufd_xmm, 3128 gen_helper_pshufhw_xmm, gen_helper_pshuflw_xmm), 3129 [0x71] = SSE_SPECIAL, /* shiftw */ 3130 [0x72] = SSE_SPECIAL, /* shiftd */ 3131 [0x73] = SSE_SPECIAL, /* shiftq */ 3132 [0x74] = MMX_OP(pcmpeqb), 3133 [0x75] = MMX_OP(pcmpeqw), 3134 [0x76] = MMX_OP(pcmpeql), 3135 [0x77] = SSE_SPECIAL, /* emms */ 3136 [0x78] = SSE_SPECIAL, /* extrq_i, insertq_i (sse4a) */ 3137 [0x79] = OP(op1, SSE_OPF_V0, 3138 NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r), 3139 [0x7c] = OP(op2, 0, 3140 NULL, gen_helper_haddpd_xmm, NULL, gen_helper_haddps_xmm), 3141 [0x7d] = OP(op2, 0, 3142 NULL, gen_helper_hsubpd_xmm, NULL, gen_helper_hsubps_xmm), 3143 [0x7e] = SSE_SPECIAL, /* movd, movd, , movq */ 3144 [0x7f] = SSE_SPECIAL, /* movq, movdqa, movdqu */ 3145 [0xc4] = SSE_SPECIAL, /* pinsrw */ 3146 [0xc5] = SSE_SPECIAL, /* pextrw */ 3147 [0xd0] = OP(op2, 0, 3148 NULL, gen_helper_addsubpd_xmm, NULL, gen_helper_addsubps_xmm), 3149 [0xd1] = MMX_OP(psrlw), 3150 [0xd2] = MMX_OP(psrld), 3151 [0xd3] = MMX_OP(psrlq), 3152 [0xd4] = MMX_OP(paddq), 3153 [0xd5] = MMX_OP(pmullw), 3154 [0xd6] = SSE_SPECIAL, 3155 [0xd7] = SSE_SPECIAL, /* pmovmskb */ 3156 [0xd8] = MMX_OP(psubusb), 3157 [0xd9] = MMX_OP(psubusw), 3158 [0xda] = MMX_OP(pminub), 3159 [0xdb] = MMX_OP(pand), 3160 [0xdc] = MMX_OP(paddusb), 3161 [0xdd] = MMX_OP(paddusw), 3162 [0xde] = MMX_OP(pmaxub), 3163 [0xdf] = MMX_OP(pandn), 3164 [0xe0] = MMX_OP(pavgb), 3165 [0xe1] = MMX_OP(psraw), 3166 [0xe2] = MMX_OP(psrad), 3167 [0xe3] = MMX_OP(pavgw), 3168 [0xe4] = MMX_OP(pmulhuw), 3169 [0xe5] = MMX_OP(pmulhw), 3170 [0xe6] = OP(op1, SSE_OPF_V0, 3171 NULL, gen_helper_cvttpd2dq_xmm, 3172 gen_helper_cvtdq2pd_xmm, gen_helper_cvtpd2dq_xmm), 3173 [0xe7] = SSE_SPECIAL, /* movntq, movntq */ 3174 [0xe8] = MMX_OP(psubsb), 3175 [0xe9] = MMX_OP(psubsw), 3176 [0xea] = MMX_OP(pminsw), 3177 [0xeb] = MMX_OP(por), 3178 [0xec] = MMX_OP(paddsb), 3179 [0xed] = MMX_OP(paddsw), 3180 [0xee] = MMX_OP(pmaxsw), 3181 [0xef] = MMX_OP(pxor), 3182 [0xf0] = SSE_SPECIAL, /* lddqu */ 3183 [0xf1] = MMX_OP(psllw), 3184 [0xf2] = MMX_OP(pslld), 3185 [0xf3] = MMX_OP(psllq), 3186 [0xf4] = MMX_OP(pmuludq), 3187 [0xf5] = MMX_OP(pmaddwd), 3188 [0xf6] = MMX_OP(psadbw), 3189 [0xf7] = OP(op1t, SSE_OPF_MMX | SSE_OPF_V0, 3190 gen_helper_maskmov_mmx, gen_helper_maskmov_xmm, NULL, NULL), 3191 [0xf8] = MMX_OP(psubb), 3192 [0xf9] = MMX_OP(psubw), 3193 [0xfa] = MMX_OP(psubl), 3194 [0xfb] = MMX_OP(psubq), 3195 [0xfc] = MMX_OP(paddb), 3196 [0xfd] = MMX_OP(paddw), 3197 [0xfe] = MMX_OP(paddl), 3198 }; 3199 #undef MMX_OP 3200 #undef OP 3201 #undef SSE_FOP 3202 #undef SSE_OP 3203 #undef SSE_SPECIAL 3204 3205 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm } 3206 3207 static const SSEFunc_0_eppp sse_op_table2[3 * 8][2] = { 3208 [0 + 2] = MMX_OP2(psrlw), 3209 [0 + 4] = MMX_OP2(psraw), 3210 [0 + 6] = MMX_OP2(psllw), 3211 [8 + 2] = MMX_OP2(psrld), 3212 [8 + 4] = MMX_OP2(psrad), 3213 [8 + 6] = MMX_OP2(pslld), 3214 [16 + 2] = MMX_OP2(psrlq), 3215 [16 + 3] = { NULL, gen_helper_psrldq_xmm }, 3216 [16 + 6] = MMX_OP2(psllq), 3217 [16 + 7] = { NULL, gen_helper_pslldq_xmm }, 3218 }; 3219 3220 static const SSEFunc_0_epi sse_op_table3ai[] = { 3221 gen_helper_cvtsi2ss, 3222 gen_helper_cvtsi2sd 3223 }; 3224 3225 #ifdef TARGET_X86_64 3226 static const SSEFunc_0_epl sse_op_table3aq[] = { 3227 gen_helper_cvtsq2ss, 3228 gen_helper_cvtsq2sd 3229 }; 3230 #endif 3231 3232 static const SSEFunc_i_ep sse_op_table3bi[] = { 3233 gen_helper_cvttss2si, 3234 gen_helper_cvtss2si, 3235 gen_helper_cvttsd2si, 3236 gen_helper_cvtsd2si 3237 }; 3238 3239 #ifdef TARGET_X86_64 3240 static const SSEFunc_l_ep sse_op_table3bq[] = { 3241 gen_helper_cvttss2sq, 3242 gen_helper_cvtss2sq, 3243 gen_helper_cvttsd2sq, 3244 gen_helper_cvtsd2sq 3245 }; 3246 #endif 3247 3248 #define SSE_CMP(x) { \ 3249 gen_helper_ ## x ## ps ## _xmm, gen_helper_ ## x ## pd ## _xmm, \ 3250 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd} 3251 static const SSEFunc_0_eppp sse_op_table4[8][4] = { 3252 SSE_CMP(cmpeq), 3253 SSE_CMP(cmplt), 3254 SSE_CMP(cmple), 3255 SSE_CMP(cmpunord), 3256 SSE_CMP(cmpneq), 3257 SSE_CMP(cmpnlt), 3258 SSE_CMP(cmpnle), 3259 SSE_CMP(cmpord), 3260 }; 3261 #undef SSE_CMP 3262 3263 static void gen_helper_pavgusb(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b) 3264 { 3265 gen_helper_pavgb_mmx(env, reg_a, reg_a, reg_b); 3266 } 3267 3268 static const SSEFunc_0_epp sse_op_table5[256] = { 3269 [0x0c] = gen_helper_pi2fw, 3270 [0x0d] = gen_helper_pi2fd, 3271 [0x1c] = gen_helper_pf2iw, 3272 [0x1d] = gen_helper_pf2id, 3273 [0x8a] = gen_helper_pfnacc, 3274 [0x8e] = gen_helper_pfpnacc, 3275 [0x90] = gen_helper_pfcmpge, 3276 [0x94] = gen_helper_pfmin, 3277 [0x96] = gen_helper_pfrcp, 3278 [0x97] = gen_helper_pfrsqrt, 3279 [0x9a] = gen_helper_pfsub, 3280 [0x9e] = gen_helper_pfadd, 3281 [0xa0] = gen_helper_pfcmpgt, 3282 [0xa4] = gen_helper_pfmax, 3283 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */ 3284 [0xa7] = gen_helper_movq, /* pfrsqit1 */ 3285 [0xaa] = gen_helper_pfsubr, 3286 [0xae] = gen_helper_pfacc, 3287 [0xb0] = gen_helper_pfcmpeq, 3288 [0xb4] = gen_helper_pfmul, 3289 [0xb6] = gen_helper_movq, /* pfrcpit2 */ 3290 [0xb7] = gen_helper_pmulhrw_mmx, 3291 [0xbb] = gen_helper_pswapd, 3292 [0xbf] = gen_helper_pavgusb, 3293 }; 3294 3295 struct SSEOpHelper_table6 { 3296 SSEFuncs fn[2]; 3297 uint32_t ext_mask; 3298 int flags; 3299 }; 3300 3301 struct SSEOpHelper_table7 { 3302 union { 3303 SSEFunc_0_eppi op1; 3304 SSEFunc_0_epppi op2; 3305 SSEFunc_0_epppp op3; 3306 } fn[2]; 3307 uint32_t ext_mask; 3308 int flags; 3309 }; 3310 3311 #define gen_helper_special_xmm NULL 3312 3313 #define OP(name, op, flags, ext, mmx_name) \ 3314 {{{.op = mmx_name}, {.op = gen_helper_ ## name ## _xmm} }, \ 3315 CPUID_EXT_ ## ext, flags} 3316 #define BINARY_OP_MMX(name, ext) \ 3317 OP(name, op2, SSE_OPF_MMX, ext, gen_helper_ ## name ## _mmx) 3318 #define BINARY_OP(name, ext, flags) \ 3319 OP(name, op2, flags, ext, NULL) 3320 #define UNARY_OP_MMX(name, ext) \ 3321 OP(name, op1, SSE_OPF_V0 | SSE_OPF_MMX, ext, gen_helper_ ## name ## _mmx) 3322 #define UNARY_OP(name, ext, flags) \ 3323 OP(name, op1, SSE_OPF_V0 | flags, ext, NULL) 3324 #define BLENDV_OP(name, ext, flags) OP(name, op3, SSE_OPF_BLENDV, ext, NULL) 3325 #define CMP_OP(name, ext) OP(name, op1, SSE_OPF_CMP | SSE_OPF_V0, ext, NULL) 3326 #define SPECIAL_OP(ext) OP(special, op1, SSE_OPF_SPECIAL, ext, NULL) 3327 3328 /* prefix [66] 0f 38 */ 3329 static const struct SSEOpHelper_table6 sse_op_table6[256] = { 3330 [0x00] = BINARY_OP_MMX(pshufb, SSSE3), 3331 [0x01] = BINARY_OP_MMX(phaddw, SSSE3), 3332 [0x02] = BINARY_OP_MMX(phaddd, SSSE3), 3333 [0x03] = BINARY_OP_MMX(phaddsw, SSSE3), 3334 [0x04] = BINARY_OP_MMX(pmaddubsw, SSSE3), 3335 [0x05] = BINARY_OP_MMX(phsubw, SSSE3), 3336 [0x06] = BINARY_OP_MMX(phsubd, SSSE3), 3337 [0x07] = BINARY_OP_MMX(phsubsw, SSSE3), 3338 [0x08] = BINARY_OP_MMX(psignb, SSSE3), 3339 [0x09] = BINARY_OP_MMX(psignw, SSSE3), 3340 [0x0a] = BINARY_OP_MMX(psignd, SSSE3), 3341 [0x0b] = BINARY_OP_MMX(pmulhrsw, SSSE3), 3342 [0x10] = BLENDV_OP(pblendvb, SSE41, SSE_OPF_MMX), 3343 [0x14] = BLENDV_OP(blendvps, SSE41, 0), 3344 [0x15] = BLENDV_OP(blendvpd, SSE41, 0), 3345 [0x17] = CMP_OP(ptest, SSE41), 3346 [0x1c] = UNARY_OP_MMX(pabsb, SSSE3), 3347 [0x1d] = UNARY_OP_MMX(pabsw, SSSE3), 3348 [0x1e] = UNARY_OP_MMX(pabsd, SSSE3), 3349 [0x20] = UNARY_OP(pmovsxbw, SSE41, SSE_OPF_MMX), 3350 [0x21] = UNARY_OP(pmovsxbd, SSE41, SSE_OPF_MMX), 3351 [0x22] = UNARY_OP(pmovsxbq, SSE41, SSE_OPF_MMX), 3352 [0x23] = UNARY_OP(pmovsxwd, SSE41, SSE_OPF_MMX), 3353 [0x24] = UNARY_OP(pmovsxwq, SSE41, SSE_OPF_MMX), 3354 [0x25] = UNARY_OP(pmovsxdq, SSE41, SSE_OPF_MMX), 3355 [0x28] = BINARY_OP(pmuldq, SSE41, SSE_OPF_MMX), 3356 [0x29] = BINARY_OP(pcmpeqq, SSE41, SSE_OPF_MMX), 3357 [0x2a] = SPECIAL_OP(SSE41), /* movntdqa */ 3358 [0x2b] = BINARY_OP(packusdw, SSE41, SSE_OPF_MMX), 3359 [0x30] = UNARY_OP(pmovzxbw, SSE41, SSE_OPF_MMX), 3360 [0x31] = UNARY_OP(pmovzxbd, SSE41, SSE_OPF_MMX), 3361 [0x32] = UNARY_OP(pmovzxbq, SSE41, SSE_OPF_MMX), 3362 [0x33] = UNARY_OP(pmovzxwd, SSE41, SSE_OPF_MMX), 3363 [0x34] = UNARY_OP(pmovzxwq, SSE41, SSE_OPF_MMX), 3364 [0x35] = UNARY_OP(pmovzxdq, SSE41, SSE_OPF_MMX), 3365 [0x37] = BINARY_OP(pcmpgtq, SSE41, SSE_OPF_MMX), 3366 [0x38] = BINARY_OP(pminsb, SSE41, SSE_OPF_MMX), 3367 [0x39] = BINARY_OP(pminsd, SSE41, SSE_OPF_MMX), 3368 [0x3a] = BINARY_OP(pminuw, SSE41, SSE_OPF_MMX), 3369 [0x3b] = BINARY_OP(pminud, SSE41, SSE_OPF_MMX), 3370 [0x3c] = BINARY_OP(pmaxsb, SSE41, SSE_OPF_MMX), 3371 [0x3d] = BINARY_OP(pmaxsd, SSE41, SSE_OPF_MMX), 3372 [0x3e] = BINARY_OP(pmaxuw, SSE41, SSE_OPF_MMX), 3373 [0x3f] = BINARY_OP(pmaxud, SSE41, SSE_OPF_MMX), 3374 [0x40] = BINARY_OP(pmulld, SSE41, SSE_OPF_MMX), 3375 [0x41] = UNARY_OP(phminposuw, SSE41, 0), 3376 [0xdb] = UNARY_OP(aesimc, AES, 0), 3377 [0xdc] = BINARY_OP(aesenc, AES, 0), 3378 [0xdd] = BINARY_OP(aesenclast, AES, 0), 3379 [0xde] = BINARY_OP(aesdec, AES, 0), 3380 [0xdf] = BINARY_OP(aesdeclast, AES, 0), 3381 }; 3382 3383 /* prefix [66] 0f 3a */ 3384 static const struct SSEOpHelper_table7 sse_op_table7[256] = { 3385 [0x08] = UNARY_OP(roundps, SSE41, 0), 3386 [0x09] = UNARY_OP(roundpd, SSE41, 0), 3387 [0x0a] = BINARY_OP(roundss, SSE41, SSE_OPF_SCALAR), 3388 [0x0b] = BINARY_OP(roundsd, SSE41, SSE_OPF_SCALAR), 3389 [0x0c] = BINARY_OP(blendps, SSE41, 0), 3390 [0x0d] = BINARY_OP(blendpd, SSE41, 0), 3391 [0x0e] = BINARY_OP(pblendw, SSE41, SSE_OPF_MMX), 3392 [0x0f] = BINARY_OP_MMX(palignr, SSSE3), 3393 [0x14] = SPECIAL_OP(SSE41), /* pextrb */ 3394 [0x15] = SPECIAL_OP(SSE41), /* pextrw */ 3395 [0x16] = SPECIAL_OP(SSE41), /* pextrd/pextrq */ 3396 [0x17] = SPECIAL_OP(SSE41), /* extractps */ 3397 [0x20] = SPECIAL_OP(SSE41), /* pinsrb */ 3398 [0x21] = SPECIAL_OP(SSE41), /* insertps */ 3399 [0x22] = SPECIAL_OP(SSE41), /* pinsrd/pinsrq */ 3400 [0x40] = BINARY_OP(dpps, SSE41, 0), 3401 [0x41] = BINARY_OP(dppd, SSE41, 0), 3402 [0x42] = BINARY_OP(mpsadbw, SSE41, SSE_OPF_MMX), 3403 [0x44] = BINARY_OP(pclmulqdq, PCLMULQDQ, 0), 3404 [0x60] = CMP_OP(pcmpestrm, SSE42), 3405 [0x61] = CMP_OP(pcmpestri, SSE42), 3406 [0x62] = CMP_OP(pcmpistrm, SSE42), 3407 [0x63] = CMP_OP(pcmpistri, SSE42), 3408 [0xdf] = UNARY_OP(aeskeygenassist, AES, 0), 3409 }; 3410 3411 #undef OP 3412 #undef BINARY_OP_MMX 3413 #undef BINARY_OP 3414 #undef UNARY_OP_MMX 3415 #undef UNARY_OP 3416 #undef BLENDV_OP 3417 #undef SPECIAL_OP 3418 3419 /* VEX prefix not allowed */ 3420 #define CHECK_NO_VEX(s) do { \ 3421 if (s->prefix & PREFIX_VEX) \ 3422 goto illegal_op; \ 3423 } while (0) 3424 3425 static void gen_sse(CPUX86State *env, DisasContext *s, int b) 3426 { 3427 int b1, op1_offset, op2_offset, is_xmm, val; 3428 int modrm, mod, rm, reg; 3429 int sse_op_flags; 3430 SSEFuncs sse_op_fn; 3431 const struct SSEOpHelper_table6 *op6; 3432 const struct SSEOpHelper_table7 *op7; 3433 MemOp ot; 3434 3435 b &= 0xff; 3436 if (s->prefix & PREFIX_DATA) 3437 b1 = 1; 3438 else if (s->prefix & PREFIX_REPZ) 3439 b1 = 2; 3440 else if (s->prefix & PREFIX_REPNZ) 3441 b1 = 3; 3442 else 3443 b1 = 0; 3444 sse_op_flags = sse_op_table1[b].flags; 3445 sse_op_fn = sse_op_table1[b].fn[b1]; 3446 if ((sse_op_flags & (SSE_OPF_SPECIAL | SSE_OPF_3DNOW)) == 0 3447 && !sse_op_fn.op1) { 3448 goto unknown_op; 3449 } 3450 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) { 3451 is_xmm = 1; 3452 } else { 3453 if (b1 == 0) { 3454 /* MMX case */ 3455 is_xmm = 0; 3456 } else { 3457 is_xmm = 1; 3458 } 3459 } 3460 if (sse_op_flags & SSE_OPF_3DNOW) { 3461 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) { 3462 goto illegal_op; 3463 } 3464 } 3465 /* simple MMX/SSE operation */ 3466 if (s->flags & HF_TS_MASK) { 3467 gen_exception(s, EXCP07_PREX); 3468 return; 3469 } 3470 if (s->flags & HF_EM_MASK) { 3471 illegal_op: 3472 gen_illegal_opcode(s); 3473 return; 3474 } 3475 if (is_xmm 3476 && !(s->flags & HF_OSFXSR_MASK) 3477 && (b != 0x38 && b != 0x3a)) { 3478 goto unknown_op; 3479 } 3480 if (b == 0x0e) { 3481 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) { 3482 /* If we were fully decoding this we might use illegal_op. */ 3483 goto unknown_op; 3484 } 3485 /* femms */ 3486 gen_helper_emms(cpu_env); 3487 return; 3488 } 3489 if (b == 0x77) { 3490 /* emms */ 3491 gen_helper_emms(cpu_env); 3492 return; 3493 } 3494 /* prepare MMX state (XXX: optimize by storing fptt and fptags in 3495 the static cpu state) */ 3496 if (!is_xmm) { 3497 gen_helper_enter_mmx(cpu_env); 3498 } 3499 3500 modrm = x86_ldub_code(env, s); 3501 reg = ((modrm >> 3) & 7); 3502 if (is_xmm) { 3503 reg |= REX_R(s); 3504 } 3505 mod = (modrm >> 6) & 3; 3506 if (sse_op_flags & SSE_OPF_SPECIAL) { 3507 b |= (b1 << 8); 3508 switch(b) { 3509 case 0x0e7: /* movntq */ 3510 CHECK_NO_VEX(s); 3511 if (mod == 3) { 3512 goto illegal_op; 3513 } 3514 gen_lea_modrm(env, s, modrm); 3515 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx)); 3516 break; 3517 case 0x1e7: /* movntdq */ 3518 case 0x02b: /* movntps */ 3519 case 0x12b: /* movntpd */ 3520 if (mod == 3) 3521 goto illegal_op; 3522 gen_lea_modrm(env, s, modrm); 3523 gen_sto_env_A0(s, XMM_OFFSET(reg), true); 3524 break; 3525 case 0x3f0: /* lddqu */ 3526 if (mod == 3) 3527 goto illegal_op; 3528 gen_lea_modrm(env, s, modrm); 3529 gen_ldo_env_A0(s, XMM_OFFSET(reg), true); 3530 break; 3531 case 0x22b: /* movntss */ 3532 case 0x32b: /* movntsd */ 3533 if (mod == 3) 3534 goto illegal_op; 3535 gen_lea_modrm(env, s, modrm); 3536 if (b1 & 1) { 3537 gen_stq_env_A0(s, offsetof(CPUX86State, 3538 xmm_regs[reg].ZMM_Q(0))); 3539 } else { 3540 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, 3541 xmm_regs[reg].ZMM_L(0))); 3542 gen_op_st_v(s, MO_32, s->T0, s->A0); 3543 } 3544 break; 3545 case 0x6e: /* movd mm, ea */ 3546 CHECK_NO_VEX(s); 3547 #ifdef TARGET_X86_64 3548 if (s->dflag == MO_64) { 3549 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0); 3550 tcg_gen_st_tl(s->T0, cpu_env, 3551 offsetof(CPUX86State, fpregs[reg].mmx)); 3552 } else 3553 #endif 3554 { 3555 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0); 3556 tcg_gen_addi_ptr(s->ptr0, cpu_env, 3557 offsetof(CPUX86State,fpregs[reg].mmx)); 3558 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3559 gen_helper_movl_mm_T0_mmx(s->ptr0, s->tmp2_i32); 3560 } 3561 break; 3562 case 0x16e: /* movd xmm, ea */ 3563 #ifdef TARGET_X86_64 3564 if (s->dflag == MO_64) { 3565 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0); 3566 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(reg)); 3567 gen_helper_movq_mm_T0_xmm(s->ptr0, s->T0); 3568 } else 3569 #endif 3570 { 3571 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0); 3572 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(reg)); 3573 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3574 gen_helper_movl_mm_T0_xmm(s->ptr0, s->tmp2_i32); 3575 } 3576 break; 3577 case 0x6f: /* movq mm, ea */ 3578 CHECK_NO_VEX(s); 3579 if (mod != 3) { 3580 gen_lea_modrm(env, s, modrm); 3581 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx)); 3582 } else { 3583 rm = (modrm & 7); 3584 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, 3585 offsetof(CPUX86State,fpregs[rm].mmx)); 3586 tcg_gen_st_i64(s->tmp1_i64, cpu_env, 3587 offsetof(CPUX86State,fpregs[reg].mmx)); 3588 } 3589 break; 3590 case 0x010: /* movups */ 3591 case 0x110: /* movupd */ 3592 case 0x028: /* movaps */ 3593 case 0x128: /* movapd */ 3594 case 0x16f: /* movdqa xmm, ea */ 3595 case 0x26f: /* movdqu xmm, ea */ 3596 if (mod != 3) { 3597 gen_lea_modrm(env, s, modrm); 3598 gen_ldo_env_A0(s, XMM_OFFSET(reg), 3599 /* movaps, movapd, movdqa */ 3600 b == 0x028 || b == 0x128 || b == 0x16f); 3601 } else { 3602 rm = (modrm & 7) | REX_B(s); 3603 gen_op_movo(s, XMM_OFFSET(reg), XMM_OFFSET(rm)); 3604 } 3605 break; 3606 case 0x210: /* movss xmm, ea */ 3607 if (mod != 3) { 3608 gen_lea_modrm(env, s, modrm); 3609 gen_op_ld_v(s, MO_32, s->T0, s->A0); 3610 tcg_gen_st32_tl(s->T0, cpu_env, 3611 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0))); 3612 tcg_gen_movi_tl(s->T0, 0); 3613 tcg_gen_st32_tl(s->T0, cpu_env, 3614 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1))); 3615 tcg_gen_st32_tl(s->T0, cpu_env, 3616 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2))); 3617 tcg_gen_st32_tl(s->T0, cpu_env, 3618 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3))); 3619 } else { 3620 rm = (modrm & 7) | REX_B(s); 3621 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, 3622 offsetof(CPUX86State, xmm_regs[rm].ZMM_L(0))); 3623 tcg_gen_st_i32(s->tmp2_i32, cpu_env, 3624 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0))); 3625 } 3626 break; 3627 case 0x310: /* movsd xmm, ea */ 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 tcg_gen_movi_tl(s->T0, 0); 3633 tcg_gen_st32_tl(s->T0, cpu_env, 3634 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2))); 3635 tcg_gen_st32_tl(s->T0, cpu_env, 3636 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3))); 3637 } else { 3638 rm = (modrm & 7) | REX_B(s); 3639 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)), 3640 offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(0))); 3641 } 3642 break; 3643 case 0x012: /* movlps */ 3644 case 0x112: /* movlpd */ 3645 if (mod != 3) { 3646 gen_lea_modrm(env, s, modrm); 3647 gen_ldq_env_A0(s, offsetof(CPUX86State, 3648 xmm_regs[reg].ZMM_Q(0))); 3649 } else { 3650 /* movhlps */ 3651 rm = (modrm & 7) | REX_B(s); 3652 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)), 3653 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1))); 3654 } 3655 break; 3656 case 0x212: /* movsldup */ 3657 if (mod != 3) { 3658 gen_lea_modrm(env, s, modrm); 3659 gen_ldo_env_A0(s, XMM_OFFSET(reg), true); 3660 } else { 3661 rm = (modrm & 7) | REX_B(s); 3662 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)), 3663 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0))); 3664 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)), 3665 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2))); 3666 } 3667 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1)), 3668 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0))); 3669 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)), 3670 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2))); 3671 break; 3672 case 0x312: /* movddup */ 3673 if (mod != 3) { 3674 gen_lea_modrm(env, s, modrm); 3675 gen_ldq_env_A0(s, offsetof(CPUX86State, 3676 xmm_regs[reg].ZMM_Q(0))); 3677 } else { 3678 rm = (modrm & 7) | REX_B(s); 3679 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)), 3680 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0))); 3681 } 3682 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)), 3683 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0))); 3684 break; 3685 case 0x016: /* movhps */ 3686 case 0x116: /* movhpd */ 3687 if (mod != 3) { 3688 gen_lea_modrm(env, s, modrm); 3689 gen_ldq_env_A0(s, offsetof(CPUX86State, 3690 xmm_regs[reg].ZMM_Q(1))); 3691 } else { 3692 /* movlhps */ 3693 rm = (modrm & 7) | REX_B(s); 3694 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)), 3695 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0))); 3696 } 3697 break; 3698 case 0x216: /* movshdup */ 3699 if (mod != 3) { 3700 gen_lea_modrm(env, s, modrm); 3701 gen_ldo_env_A0(s, XMM_OFFSET(reg), true); 3702 } else { 3703 rm = (modrm & 7) | REX_B(s); 3704 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1)), 3705 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1))); 3706 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)), 3707 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3))); 3708 } 3709 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)), 3710 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1))); 3711 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)), 3712 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3))); 3713 break; 3714 case 0x178: 3715 case 0x378: 3716 CHECK_NO_VEX(s); 3717 { 3718 int bit_index, field_length; 3719 3720 if (b1 == 1 && reg != 0) 3721 goto illegal_op; 3722 field_length = x86_ldub_code(env, s) & 0x3F; 3723 bit_index = x86_ldub_code(env, s) & 0x3F; 3724 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(reg)); 3725 if (b1 == 1) 3726 gen_helper_extrq_i(cpu_env, s->ptr0, 3727 tcg_const_i32(bit_index), 3728 tcg_const_i32(field_length)); 3729 else { 3730 if (mod != 3) { 3731 gen_lea_modrm(env, s, modrm); 3732 op2_offset = offsetof(CPUX86State, xmm_t0); 3733 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0))); 3734 } else { 3735 rm = (modrm & 7) | REX_B(s); 3736 op2_offset = ZMM_OFFSET(rm); 3737 } 3738 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 3739 gen_helper_insertq_i(cpu_env, s->ptr0, s->ptr1, 3740 tcg_const_i32(bit_index), 3741 tcg_const_i32(field_length)); 3742 } 3743 } 3744 break; 3745 case 0x7e: /* movd ea, mm */ 3746 CHECK_NO_VEX(s); 3747 #ifdef TARGET_X86_64 3748 if (s->dflag == MO_64) { 3749 tcg_gen_ld_i64(s->T0, cpu_env, 3750 offsetof(CPUX86State,fpregs[reg].mmx)); 3751 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1); 3752 } else 3753 #endif 3754 { 3755 tcg_gen_ld32u_tl(s->T0, cpu_env, 3756 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0))); 3757 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1); 3758 } 3759 break; 3760 case 0x17e: /* movd ea, xmm */ 3761 #ifdef TARGET_X86_64 3762 if (s->dflag == MO_64) { 3763 tcg_gen_ld_i64(s->T0, cpu_env, 3764 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0))); 3765 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1); 3766 } else 3767 #endif 3768 { 3769 tcg_gen_ld32u_tl(s->T0, cpu_env, 3770 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0))); 3771 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1); 3772 } 3773 break; 3774 case 0x27e: /* movq xmm, ea */ 3775 if (mod != 3) { 3776 gen_lea_modrm(env, s, modrm); 3777 gen_ldq_env_A0(s, offsetof(CPUX86State, 3778 xmm_regs[reg].ZMM_Q(0))); 3779 } else { 3780 rm = (modrm & 7) | REX_B(s); 3781 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)), 3782 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0))); 3783 } 3784 gen_op_movq_env_0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1))); 3785 break; 3786 case 0x7f: /* movq ea, mm */ 3787 CHECK_NO_VEX(s); 3788 if (mod != 3) { 3789 gen_lea_modrm(env, s, modrm); 3790 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx)); 3791 } else { 3792 rm = (modrm & 7); 3793 gen_op_movq(s, offsetof(CPUX86State, fpregs[rm].mmx), 3794 offsetof(CPUX86State,fpregs[reg].mmx)); 3795 } 3796 break; 3797 case 0x011: /* movups */ 3798 case 0x111: /* movupd */ 3799 case 0x029: /* movaps */ 3800 case 0x129: /* movapd */ 3801 case 0x17f: /* movdqa ea, xmm */ 3802 case 0x27f: /* movdqu ea, xmm */ 3803 if (mod != 3) { 3804 gen_lea_modrm(env, s, modrm); 3805 gen_sto_env_A0(s, XMM_OFFSET(reg), 3806 /* movaps, movapd, movdqa */ 3807 b == 0x029 || b == 0x129 || b == 0x17f); 3808 } else { 3809 rm = (modrm & 7) | REX_B(s); 3810 gen_op_movo(s, XMM_OFFSET(rm), XMM_OFFSET(reg)); 3811 } 3812 break; 3813 case 0x211: /* movss ea, xmm */ 3814 if (mod != 3) { 3815 gen_lea_modrm(env, s, modrm); 3816 tcg_gen_ld32u_tl(s->T0, cpu_env, 3817 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0))); 3818 gen_op_st_v(s, MO_32, s->T0, s->A0); 3819 } else { 3820 rm = (modrm & 7) | REX_B(s); 3821 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[rm].ZMM_L(0)), 3822 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0))); 3823 } 3824 break; 3825 case 0x311: /* movsd ea, xmm */ 3826 if (mod != 3) { 3827 gen_lea_modrm(env, s, modrm); 3828 gen_stq_env_A0(s, offsetof(CPUX86State, 3829 xmm_regs[reg].ZMM_Q(0))); 3830 } else { 3831 rm = (modrm & 7) | REX_B(s); 3832 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(0)), 3833 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0))); 3834 } 3835 break; 3836 case 0x013: /* movlps */ 3837 case 0x113: /* movlpd */ 3838 if (mod != 3) { 3839 gen_lea_modrm(env, s, modrm); 3840 gen_stq_env_A0(s, offsetof(CPUX86State, 3841 xmm_regs[reg].ZMM_Q(0))); 3842 } else { 3843 goto illegal_op; 3844 } 3845 break; 3846 case 0x017: /* movhps */ 3847 case 0x117: /* movhpd */ 3848 if (mod != 3) { 3849 gen_lea_modrm(env, s, modrm); 3850 gen_stq_env_A0(s, offsetof(CPUX86State, 3851 xmm_regs[reg].ZMM_Q(1))); 3852 } else { 3853 goto illegal_op; 3854 } 3855 break; 3856 case 0x71: /* shift mm, im */ 3857 case 0x72: 3858 case 0x73: 3859 case 0x171: /* shift xmm, im */ 3860 case 0x172: 3861 case 0x173: 3862 val = x86_ldub_code(env, s); 3863 if (is_xmm) { 3864 tcg_gen_movi_tl(s->T0, val); 3865 tcg_gen_st32_tl(s->T0, cpu_env, 3866 offsetof(CPUX86State, xmm_t0.ZMM_L(0))); 3867 tcg_gen_movi_tl(s->T0, 0); 3868 tcg_gen_st32_tl(s->T0, cpu_env, 3869 offsetof(CPUX86State, xmm_t0.ZMM_L(1))); 3870 op1_offset = offsetof(CPUX86State,xmm_t0); 3871 } else { 3872 CHECK_NO_VEX(s); 3873 tcg_gen_movi_tl(s->T0, val); 3874 tcg_gen_st32_tl(s->T0, cpu_env, 3875 offsetof(CPUX86State, mmx_t0.MMX_L(0))); 3876 tcg_gen_movi_tl(s->T0, 0); 3877 tcg_gen_st32_tl(s->T0, cpu_env, 3878 offsetof(CPUX86State, mmx_t0.MMX_L(1))); 3879 op1_offset = offsetof(CPUX86State,mmx_t0); 3880 } 3881 assert(b1 < 2); 3882 SSEFunc_0_eppp fn = sse_op_table2[((b - 1) & 3) * 8 + 3883 (((modrm >> 3)) & 7)][b1]; 3884 if (!fn) { 3885 goto unknown_op; 3886 } 3887 if (is_xmm) { 3888 rm = (modrm & 7) | REX_B(s); 3889 op2_offset = ZMM_OFFSET(rm); 3890 } else { 3891 rm = (modrm & 7); 3892 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 3893 } 3894 tcg_gen_addi_ptr(s->ptr0, cpu_env, op2_offset); 3895 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 3896 tcg_gen_addi_ptr(s->ptr2, cpu_env, op1_offset); 3897 fn(cpu_env, s->ptr0, s->ptr1, s->ptr2); 3898 break; 3899 case 0x050: /* movmskps */ 3900 rm = (modrm & 7) | REX_B(s); 3901 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(rm)); 3902 gen_helper_movmskps_xmm(s->tmp2_i32, cpu_env, s->ptr0); 3903 tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32); 3904 break; 3905 case 0x150: /* movmskpd */ 3906 rm = (modrm & 7) | REX_B(s); 3907 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(rm)); 3908 gen_helper_movmskpd_xmm(s->tmp2_i32, cpu_env, s->ptr0); 3909 tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32); 3910 break; 3911 case 0x02a: /* cvtpi2ps */ 3912 case 0x12a: /* cvtpi2pd */ 3913 CHECK_NO_VEX(s); 3914 gen_helper_enter_mmx(cpu_env); 3915 if (mod != 3) { 3916 gen_lea_modrm(env, s, modrm); 3917 op2_offset = offsetof(CPUX86State,mmx_t0); 3918 gen_ldq_env_A0(s, op2_offset); 3919 } else { 3920 rm = (modrm & 7); 3921 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 3922 } 3923 op1_offset = ZMM_OFFSET(reg); 3924 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 3925 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 3926 switch(b >> 8) { 3927 case 0x0: 3928 gen_helper_cvtpi2ps(cpu_env, s->ptr0, s->ptr1); 3929 break; 3930 default: 3931 case 0x1: 3932 gen_helper_cvtpi2pd(cpu_env, s->ptr0, s->ptr1); 3933 break; 3934 } 3935 break; 3936 case 0x22a: /* cvtsi2ss */ 3937 case 0x32a: /* cvtsi2sd */ 3938 ot = mo_64_32(s->dflag); 3939 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3940 op1_offset = ZMM_OFFSET(reg); 3941 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 3942 if (ot == MO_32) { 3943 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1]; 3944 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3945 sse_fn_epi(cpu_env, s->ptr0, s->tmp2_i32); 3946 } else { 3947 #ifdef TARGET_X86_64 3948 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1]; 3949 sse_fn_epl(cpu_env, s->ptr0, s->T0); 3950 #else 3951 goto illegal_op; 3952 #endif 3953 } 3954 break; 3955 case 0x02c: /* cvttps2pi */ 3956 case 0x12c: /* cvttpd2pi */ 3957 case 0x02d: /* cvtps2pi */ 3958 case 0x12d: /* cvtpd2pi */ 3959 CHECK_NO_VEX(s); 3960 gen_helper_enter_mmx(cpu_env); 3961 if (mod != 3) { 3962 gen_lea_modrm(env, s, modrm); 3963 op2_offset = offsetof(CPUX86State, xmm_t0.ZMM_X(0)); 3964 /* FIXME: should be 64-bit access if b1 == 0. */ 3965 gen_ldo_env_A0(s, op2_offset, !!b1); 3966 } else { 3967 rm = (modrm & 7) | REX_B(s); 3968 op2_offset = ZMM_OFFSET(rm); 3969 } 3970 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx); 3971 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 3972 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 3973 switch(b) { 3974 case 0x02c: 3975 gen_helper_cvttps2pi(cpu_env, s->ptr0, s->ptr1); 3976 break; 3977 case 0x12c: 3978 gen_helper_cvttpd2pi(cpu_env, s->ptr0, s->ptr1); 3979 break; 3980 case 0x02d: 3981 gen_helper_cvtps2pi(cpu_env, s->ptr0, s->ptr1); 3982 break; 3983 case 0x12d: 3984 gen_helper_cvtpd2pi(cpu_env, s->ptr0, s->ptr1); 3985 break; 3986 } 3987 break; 3988 case 0x22c: /* cvttss2si */ 3989 case 0x32c: /* cvttsd2si */ 3990 case 0x22d: /* cvtss2si */ 3991 case 0x32d: /* cvtsd2si */ 3992 ot = mo_64_32(s->dflag); 3993 if (mod != 3) { 3994 gen_lea_modrm(env, s, modrm); 3995 if ((b >> 8) & 1) { 3996 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0))); 3997 } else { 3998 gen_op_ld_v(s, MO_32, s->T0, s->A0); 3999 tcg_gen_st32_tl(s->T0, cpu_env, 4000 offsetof(CPUX86State, xmm_t0.ZMM_L(0))); 4001 } 4002 op2_offset = offsetof(CPUX86State,xmm_t0); 4003 } else { 4004 rm = (modrm & 7) | REX_B(s); 4005 op2_offset = ZMM_OFFSET(rm); 4006 } 4007 tcg_gen_addi_ptr(s->ptr0, cpu_env, op2_offset); 4008 if (ot == MO_32) { 4009 SSEFunc_i_ep sse_fn_i_ep = 4010 sse_op_table3bi[((b >> 7) & 2) | (b & 1)]; 4011 sse_fn_i_ep(s->tmp2_i32, cpu_env, s->ptr0); 4012 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 4013 } else { 4014 #ifdef TARGET_X86_64 4015 SSEFunc_l_ep sse_fn_l_ep = 4016 sse_op_table3bq[((b >> 7) & 2) | (b & 1)]; 4017 sse_fn_l_ep(s->T0, cpu_env, s->ptr0); 4018 #else 4019 goto illegal_op; 4020 #endif 4021 } 4022 gen_op_mov_reg_v(s, ot, reg, s->T0); 4023 break; 4024 case 0xc4: /* pinsrw */ 4025 case 0x1c4: 4026 s->rip_offset = 1; 4027 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 4028 val = x86_ldub_code(env, s); 4029 if (b1) { 4030 val &= 7; 4031 tcg_gen_st16_tl(s->T0, cpu_env, 4032 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val))); 4033 } else { 4034 CHECK_NO_VEX(s); 4035 val &= 3; 4036 tcg_gen_st16_tl(s->T0, cpu_env, 4037 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val))); 4038 } 4039 break; 4040 case 0xc5: /* pextrw */ 4041 case 0x1c5: 4042 if (mod != 3) 4043 goto illegal_op; 4044 ot = mo_64_32(s->dflag); 4045 val = x86_ldub_code(env, s); 4046 if (b1) { 4047 val &= 7; 4048 rm = (modrm & 7) | REX_B(s); 4049 tcg_gen_ld16u_tl(s->T0, cpu_env, 4050 offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val))); 4051 } else { 4052 val &= 3; 4053 rm = (modrm & 7); 4054 tcg_gen_ld16u_tl(s->T0, cpu_env, 4055 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val))); 4056 } 4057 reg = ((modrm >> 3) & 7) | REX_R(s); 4058 gen_op_mov_reg_v(s, ot, reg, s->T0); 4059 break; 4060 case 0x1d6: /* movq ea, xmm */ 4061 if (mod != 3) { 4062 gen_lea_modrm(env, s, modrm); 4063 gen_stq_env_A0(s, offsetof(CPUX86State, 4064 xmm_regs[reg].ZMM_Q(0))); 4065 } else { 4066 rm = (modrm & 7) | REX_B(s); 4067 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(0)), 4068 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0))); 4069 gen_op_movq_env_0(s, 4070 offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(1))); 4071 } 4072 break; 4073 case 0x2d6: /* movq2dq */ 4074 CHECK_NO_VEX(s); 4075 gen_helper_enter_mmx(cpu_env); 4076 rm = (modrm & 7); 4077 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)), 4078 offsetof(CPUX86State,fpregs[rm].mmx)); 4079 gen_op_movq_env_0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1))); 4080 break; 4081 case 0x3d6: /* movdq2q */ 4082 CHECK_NO_VEX(s); 4083 gen_helper_enter_mmx(cpu_env); 4084 rm = (modrm & 7) | REX_B(s); 4085 gen_op_movq(s, offsetof(CPUX86State, fpregs[reg & 7].mmx), 4086 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0))); 4087 break; 4088 case 0xd7: /* pmovmskb */ 4089 case 0x1d7: 4090 if (mod != 3) 4091 goto illegal_op; 4092 if (b1) { 4093 rm = (modrm & 7) | REX_B(s); 4094 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(rm)); 4095 gen_helper_pmovmskb_xmm(s->tmp2_i32, cpu_env, s->ptr0); 4096 } else { 4097 CHECK_NO_VEX(s); 4098 rm = (modrm & 7); 4099 tcg_gen_addi_ptr(s->ptr0, cpu_env, 4100 offsetof(CPUX86State, fpregs[rm].mmx)); 4101 gen_helper_pmovmskb_mmx(s->tmp2_i32, cpu_env, s->ptr0); 4102 } 4103 reg = ((modrm >> 3) & 7) | REX_R(s); 4104 tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32); 4105 break; 4106 4107 case 0x138: 4108 case 0x038: 4109 b = modrm; 4110 if ((b & 0xf0) == 0xf0) { 4111 goto do_0f_38_fx; 4112 } 4113 modrm = x86_ldub_code(env, s); 4114 rm = modrm & 7; 4115 reg = ((modrm >> 3) & 7) | REX_R(s); 4116 mod = (modrm >> 6) & 3; 4117 4118 assert(b1 < 2); 4119 op6 = &sse_op_table6[b]; 4120 if (op6->ext_mask == 0) { 4121 goto unknown_op; 4122 } 4123 if (!(s->cpuid_ext_features & op6->ext_mask)) { 4124 goto illegal_op; 4125 } 4126 4127 if (b1) { 4128 op1_offset = ZMM_OFFSET(reg); 4129 if (mod == 3) { 4130 op2_offset = ZMM_OFFSET(rm | REX_B(s)); 4131 } else { 4132 op2_offset = offsetof(CPUX86State,xmm_t0); 4133 gen_lea_modrm(env, s, modrm); 4134 switch (b) { 4135 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */ 4136 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */ 4137 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */ 4138 gen_ldq_env_A0(s, op2_offset + 4139 offsetof(ZMMReg, ZMM_Q(0))); 4140 break; 4141 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */ 4142 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */ 4143 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4144 s->mem_index, MO_LEUL); 4145 tcg_gen_st_i32(s->tmp2_i32, cpu_env, op2_offset + 4146 offsetof(ZMMReg, ZMM_L(0))); 4147 break; 4148 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */ 4149 tcg_gen_qemu_ld_tl(s->tmp0, s->A0, 4150 s->mem_index, MO_LEUW); 4151 tcg_gen_st16_tl(s->tmp0, cpu_env, op2_offset + 4152 offsetof(ZMMReg, ZMM_W(0))); 4153 break; 4154 case 0x2a: /* movntdqa */ 4155 gen_ldo_env_A0(s, op1_offset + offsetof(ZMMReg, ZMM_X(0)), true); 4156 return; 4157 default: 4158 gen_ldo_env_A0(s, op2_offset + offsetof(ZMMReg, ZMM_X(0)), true); 4159 } 4160 } 4161 if (!op6->fn[b1].op1) { 4162 goto illegal_op; 4163 } 4164 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 4165 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 4166 if (op6->flags & SSE_OPF_V0) { 4167 op6->fn[b1].op1(cpu_env, s->ptr0, s->ptr1); 4168 } else { 4169 tcg_gen_addi_ptr(s->ptr2, cpu_env, op1_offset); 4170 if (op6->flags & SSE_OPF_BLENDV) { 4171 TCGv_ptr mask = tcg_temp_new_ptr(); 4172 tcg_gen_addi_ptr(mask, cpu_env, ZMM_OFFSET(0)); 4173 op6->fn[b1].op3(cpu_env, s->ptr0, s->ptr2, s->ptr1, 4174 mask); 4175 tcg_temp_free_ptr(mask); 4176 } else { 4177 SSEFunc_0_eppp fn = op6->fn[b1].op2; 4178 fn(cpu_env, s->ptr0, s->ptr2, s->ptr1); 4179 } 4180 } 4181 } else { 4182 CHECK_NO_VEX(s); 4183 if ((op6->flags & SSE_OPF_MMX) == 0) { 4184 goto unknown_op; 4185 } 4186 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); 4187 if (mod == 3) { 4188 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 4189 } else { 4190 op2_offset = offsetof(CPUX86State,mmx_t0); 4191 gen_lea_modrm(env, s, modrm); 4192 gen_ldq_env_A0(s, op2_offset); 4193 } 4194 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 4195 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 4196 if (op6->flags & SSE_OPF_V0) { 4197 op6->fn[0].op1(cpu_env, s->ptr0, s->ptr1); 4198 } else { 4199 op6->fn[0].op2(cpu_env, s->ptr0, s->ptr0, s->ptr1); 4200 } 4201 } 4202 4203 if (op6->flags & SSE_OPF_CMP) { 4204 set_cc_op(s, CC_OP_EFLAGS); 4205 } 4206 break; 4207 4208 case 0x238: 4209 case 0x338: 4210 do_0f_38_fx: 4211 /* Various integer extensions at 0f 38 f[0-f]. */ 4212 b = modrm | (b1 << 8); 4213 modrm = x86_ldub_code(env, s); 4214 reg = ((modrm >> 3) & 7) | REX_R(s); 4215 4216 switch (b) { 4217 case 0x3f0: /* crc32 Gd,Eb */ 4218 case 0x3f1: /* crc32 Gd,Ey */ 4219 do_crc32: 4220 CHECK_NO_VEX(s); 4221 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) { 4222 goto illegal_op; 4223 } 4224 if ((b & 0xff) == 0xf0) { 4225 ot = MO_8; 4226 } else if (s->dflag != MO_64) { 4227 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32); 4228 } else { 4229 ot = MO_64; 4230 } 4231 4232 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[reg]); 4233 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 4234 gen_helper_crc32(s->T0, s->tmp2_i32, 4235 s->T0, tcg_const_i32(8 << ot)); 4236 4237 ot = mo_64_32(s->dflag); 4238 gen_op_mov_reg_v(s, ot, reg, s->T0); 4239 break; 4240 4241 case 0x1f0: /* crc32 or movbe */ 4242 case 0x1f1: 4243 CHECK_NO_VEX(s); 4244 /* For these insns, the f3 prefix is supposed to have priority 4245 over the 66 prefix, but that's not what we implement above 4246 setting b1. */ 4247 if (s->prefix & PREFIX_REPNZ) { 4248 goto do_crc32; 4249 } 4250 /* FALLTHRU */ 4251 case 0x0f0: /* movbe Gy,My */ 4252 case 0x0f1: /* movbe My,Gy */ 4253 CHECK_NO_VEX(s); 4254 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) { 4255 goto illegal_op; 4256 } 4257 if (s->dflag != MO_64) { 4258 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32); 4259 } else { 4260 ot = MO_64; 4261 } 4262 4263 gen_lea_modrm(env, s, modrm); 4264 if ((b & 1) == 0) { 4265 tcg_gen_qemu_ld_tl(s->T0, s->A0, 4266 s->mem_index, ot | MO_BE); 4267 gen_op_mov_reg_v(s, ot, reg, s->T0); 4268 } else { 4269 tcg_gen_qemu_st_tl(cpu_regs[reg], s->A0, 4270 s->mem_index, ot | MO_BE); 4271 } 4272 break; 4273 case 0x1f6: /* adcx Gy, Ey */ 4274 case 0x2f6: /* adox Gy, Ey */ 4275 CHECK_NO_VEX(s); 4276 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) { 4277 goto illegal_op; 4278 } else { 4279 TCGv carry_in, carry_out, zero; 4280 int end_op; 4281 4282 ot = mo_64_32(s->dflag); 4283 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 4284 4285 /* Re-use the carry-out from a previous round. */ 4286 carry_in = NULL; 4287 carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2); 4288 switch (s->cc_op) { 4289 case CC_OP_ADCX: 4290 if (b == 0x1f6) { 4291 carry_in = cpu_cc_dst; 4292 end_op = CC_OP_ADCX; 4293 } else { 4294 end_op = CC_OP_ADCOX; 4295 } 4296 break; 4297 case CC_OP_ADOX: 4298 if (b == 0x1f6) { 4299 end_op = CC_OP_ADCOX; 4300 } else { 4301 carry_in = cpu_cc_src2; 4302 end_op = CC_OP_ADOX; 4303 } 4304 break; 4305 case CC_OP_ADCOX: 4306 end_op = CC_OP_ADCOX; 4307 carry_in = carry_out; 4308 break; 4309 default: 4310 end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX); 4311 break; 4312 } 4313 /* If we can't reuse carry-out, get it out of EFLAGS. */ 4314 if (!carry_in) { 4315 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) { 4316 gen_compute_eflags(s); 4317 } 4318 carry_in = s->tmp0; 4319 tcg_gen_extract_tl(carry_in, cpu_cc_src, 4320 ctz32(b == 0x1f6 ? CC_C : CC_O), 1); 4321 } 4322 4323 switch (ot) { 4324 #ifdef TARGET_X86_64 4325 case MO_32: 4326 /* If we know TL is 64-bit, and we want a 32-bit 4327 result, just do everything in 64-bit arithmetic. */ 4328 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]); 4329 tcg_gen_ext32u_i64(s->T0, s->T0); 4330 tcg_gen_add_i64(s->T0, s->T0, cpu_regs[reg]); 4331 tcg_gen_add_i64(s->T0, s->T0, carry_in); 4332 tcg_gen_ext32u_i64(cpu_regs[reg], s->T0); 4333 tcg_gen_shri_i64(carry_out, s->T0, 32); 4334 break; 4335 #endif 4336 default: 4337 /* Otherwise compute the carry-out in two steps. */ 4338 zero = tcg_const_tl(0); 4339 tcg_gen_add2_tl(s->T0, carry_out, 4340 s->T0, zero, 4341 carry_in, zero); 4342 tcg_gen_add2_tl(cpu_regs[reg], carry_out, 4343 cpu_regs[reg], carry_out, 4344 s->T0, zero); 4345 tcg_temp_free(zero); 4346 break; 4347 } 4348 set_cc_op(s, end_op); 4349 } 4350 break; 4351 4352 } 4353 break; 4354 4355 case 0x03a: 4356 case 0x13a: 4357 b = modrm; 4358 modrm = x86_ldub_code(env, s); 4359 rm = modrm & 7; 4360 reg = ((modrm >> 3) & 7) | REX_R(s); 4361 mod = (modrm >> 6) & 3; 4362 4363 assert(b1 < 2); 4364 op7 = &sse_op_table7[b]; 4365 if (op7->ext_mask == 0) { 4366 goto unknown_op; 4367 } 4368 if (!(s->cpuid_ext_features & op7->ext_mask)) { 4369 goto illegal_op; 4370 } 4371 4372 s->rip_offset = 1; 4373 4374 if (op7->flags & SSE_OPF_SPECIAL) { 4375 /* None of the "special" ops are valid on mmx registers */ 4376 if (b1 == 0) { 4377 goto illegal_op; 4378 } 4379 ot = mo_64_32(s->dflag); 4380 rm = (modrm & 7) | REX_B(s); 4381 if (mod != 3) 4382 gen_lea_modrm(env, s, modrm); 4383 reg = ((modrm >> 3) & 7) | REX_R(s); 4384 val = x86_ldub_code(env, s); 4385 switch (b) { 4386 case 0x14: /* pextrb */ 4387 tcg_gen_ld8u_tl(s->T0, cpu_env, offsetof(CPUX86State, 4388 xmm_regs[reg].ZMM_B(val & 15))); 4389 if (mod == 3) { 4390 gen_op_mov_reg_v(s, ot, rm, s->T0); 4391 } else { 4392 tcg_gen_qemu_st_tl(s->T0, s->A0, 4393 s->mem_index, MO_UB); 4394 } 4395 break; 4396 case 0x15: /* pextrw */ 4397 tcg_gen_ld16u_tl(s->T0, cpu_env, offsetof(CPUX86State, 4398 xmm_regs[reg].ZMM_W(val & 7))); 4399 if (mod == 3) { 4400 gen_op_mov_reg_v(s, ot, rm, s->T0); 4401 } else { 4402 tcg_gen_qemu_st_tl(s->T0, s->A0, 4403 s->mem_index, MO_LEUW); 4404 } 4405 break; 4406 case 0x16: 4407 if (ot == MO_32) { /* pextrd */ 4408 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, 4409 offsetof(CPUX86State, 4410 xmm_regs[reg].ZMM_L(val & 3))); 4411 if (mod == 3) { 4412 tcg_gen_extu_i32_tl(cpu_regs[rm], s->tmp2_i32); 4413 } else { 4414 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4415 s->mem_index, MO_LEUL); 4416 } 4417 } else { /* pextrq */ 4418 #ifdef TARGET_X86_64 4419 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, 4420 offsetof(CPUX86State, 4421 xmm_regs[reg].ZMM_Q(val & 1))); 4422 if (mod == 3) { 4423 tcg_gen_mov_i64(cpu_regs[rm], s->tmp1_i64); 4424 } else { 4425 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 4426 s->mem_index, MO_LEUQ); 4427 } 4428 #else 4429 goto illegal_op; 4430 #endif 4431 } 4432 break; 4433 case 0x17: /* extractps */ 4434 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, 4435 xmm_regs[reg].ZMM_L(val & 3))); 4436 if (mod == 3) { 4437 gen_op_mov_reg_v(s, ot, rm, s->T0); 4438 } else { 4439 tcg_gen_qemu_st_tl(s->T0, s->A0, 4440 s->mem_index, MO_LEUL); 4441 } 4442 break; 4443 case 0x20: /* pinsrb */ 4444 if (mod == 3) { 4445 gen_op_mov_v_reg(s, MO_32, s->T0, rm); 4446 } else { 4447 tcg_gen_qemu_ld_tl(s->T0, s->A0, 4448 s->mem_index, MO_UB); 4449 } 4450 tcg_gen_st8_tl(s->T0, cpu_env, offsetof(CPUX86State, 4451 xmm_regs[reg].ZMM_B(val & 15))); 4452 break; 4453 case 0x21: /* insertps */ 4454 if (mod == 3) { 4455 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, 4456 offsetof(CPUX86State,xmm_regs[rm] 4457 .ZMM_L((val >> 6) & 3))); 4458 } else { 4459 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4460 s->mem_index, MO_LEUL); 4461 } 4462 tcg_gen_st_i32(s->tmp2_i32, cpu_env, 4463 offsetof(CPUX86State,xmm_regs[reg] 4464 .ZMM_L((val >> 4) & 3))); 4465 if ((val >> 0) & 1) 4466 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), 4467 cpu_env, offsetof(CPUX86State, 4468 xmm_regs[reg].ZMM_L(0))); 4469 if ((val >> 1) & 1) 4470 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), 4471 cpu_env, offsetof(CPUX86State, 4472 xmm_regs[reg].ZMM_L(1))); 4473 if ((val >> 2) & 1) 4474 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), 4475 cpu_env, offsetof(CPUX86State, 4476 xmm_regs[reg].ZMM_L(2))); 4477 if ((val >> 3) & 1) 4478 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), 4479 cpu_env, offsetof(CPUX86State, 4480 xmm_regs[reg].ZMM_L(3))); 4481 break; 4482 case 0x22: 4483 if (ot == MO_32) { /* pinsrd */ 4484 if (mod == 3) { 4485 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[rm]); 4486 } else { 4487 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4488 s->mem_index, MO_LEUL); 4489 } 4490 tcg_gen_st_i32(s->tmp2_i32, cpu_env, 4491 offsetof(CPUX86State, 4492 xmm_regs[reg].ZMM_L(val & 3))); 4493 } else { /* pinsrq */ 4494 #ifdef TARGET_X86_64 4495 if (mod == 3) { 4496 gen_op_mov_v_reg(s, ot, s->tmp1_i64, rm); 4497 } else { 4498 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 4499 s->mem_index, MO_LEUQ); 4500 } 4501 tcg_gen_st_i64(s->tmp1_i64, cpu_env, 4502 offsetof(CPUX86State, 4503 xmm_regs[reg].ZMM_Q(val & 1))); 4504 #else 4505 goto illegal_op; 4506 #endif 4507 } 4508 break; 4509 } 4510 return; 4511 } 4512 4513 if (b1 == 0) { 4514 CHECK_NO_VEX(s); 4515 /* MMX */ 4516 if ((op7->flags & SSE_OPF_MMX) == 0) { 4517 goto illegal_op; 4518 } 4519 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); 4520 if (mod == 3) { 4521 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 4522 } else { 4523 op2_offset = offsetof(CPUX86State,mmx_t0); 4524 gen_lea_modrm(env, s, modrm); 4525 gen_ldq_env_A0(s, op2_offset); 4526 } 4527 val = x86_ldub_code(env, s); 4528 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 4529 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 4530 4531 /* We only actually have one MMX instuction (palignr) */ 4532 assert(b == 0x0f); 4533 4534 op7->fn[0].op2(cpu_env, s->ptr0, s->ptr0, s->ptr1, 4535 tcg_const_i32(val)); 4536 break; 4537 } 4538 4539 /* SSE */ 4540 op1_offset = ZMM_OFFSET(reg); 4541 if (mod == 3) { 4542 op2_offset = ZMM_OFFSET(rm | REX_B(s)); 4543 } else { 4544 op2_offset = offsetof(CPUX86State, xmm_t0); 4545 gen_lea_modrm(env, s, modrm); 4546 gen_ldo_env_A0(s, op2_offset + offsetof(ZMMReg, ZMM_X(0)), true); 4547 } 4548 4549 val = x86_ldub_code(env, s); 4550 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */ 4551 set_cc_op(s, CC_OP_EFLAGS); 4552 4553 if (s->dflag == MO_64) { 4554 /* The helper must use entire 64-bit gp registers */ 4555 val |= 1 << 8; 4556 } 4557 } 4558 4559 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 4560 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 4561 if (op7->flags & SSE_OPF_V0) { 4562 op7->fn[b1].op1(cpu_env, s->ptr0, s->ptr1, tcg_const_i32(val)); 4563 } else { 4564 tcg_gen_addi_ptr(s->ptr2, cpu_env, op1_offset); 4565 op7->fn[b1].op2(cpu_env, s->ptr0, s->ptr2, s->ptr1, 4566 tcg_const_i32(val)); 4567 } 4568 if (op7->flags & SSE_OPF_CMP) { 4569 set_cc_op(s, CC_OP_EFLAGS); 4570 } 4571 break; 4572 4573 default: 4574 unknown_op: 4575 gen_unknown_opcode(env, s); 4576 return; 4577 } 4578 } else { 4579 /* generic MMX or SSE operation */ 4580 switch(b) { 4581 case 0x70: /* pshufx insn */ 4582 case 0xc6: /* pshufx insn */ 4583 case 0xc2: /* compare insns */ 4584 s->rip_offset = 1; 4585 break; 4586 default: 4587 break; 4588 } 4589 if (is_xmm) { 4590 op1_offset = ZMM_OFFSET(reg); 4591 if (mod != 3) { 4592 int sz = 4; 4593 4594 gen_lea_modrm(env, s, modrm); 4595 op2_offset = offsetof(CPUX86State, xmm_t0); 4596 4597 if (sse_op_flags & SSE_OPF_SCALAR) { 4598 if (sse_op_flags & SSE_OPF_CMP) { 4599 /* ucomis[sd], comis[sd] */ 4600 if (b1 == 0) { 4601 sz = 2; 4602 } else { 4603 sz = 3; 4604 } 4605 } else { 4606 /* Most sse scalar operations. */ 4607 if (b1 == 2) { 4608 sz = 2; 4609 } else if (b1 == 3) { 4610 sz = 3; 4611 } 4612 } 4613 } 4614 4615 switch (sz) { 4616 case 2: 4617 /* 32 bit access */ 4618 gen_op_ld_v(s, MO_32, s->T0, s->A0); 4619 tcg_gen_st32_tl(s->T0, cpu_env, 4620 offsetof(CPUX86State, xmm_t0.ZMM_L(0))); 4621 break; 4622 case 3: 4623 /* 64 bit access */ 4624 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0))); 4625 break; 4626 default: 4627 /* 128 bit access */ 4628 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_X(0)), true); 4629 break; 4630 } 4631 } else { 4632 rm = (modrm & 7) | REX_B(s); 4633 op2_offset = ZMM_OFFSET(rm); 4634 } 4635 } else { 4636 CHECK_NO_VEX(s); 4637 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); 4638 if (mod != 3) { 4639 gen_lea_modrm(env, s, modrm); 4640 op2_offset = offsetof(CPUX86State,mmx_t0); 4641 gen_ldq_env_A0(s, op2_offset); 4642 } else { 4643 rm = (modrm & 7); 4644 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 4645 } 4646 if (sse_op_flags & SSE_OPF_3DNOW) { 4647 /* 3DNow! data insns */ 4648 val = x86_ldub_code(env, s); 4649 SSEFunc_0_epp op_3dnow = sse_op_table5[val]; 4650 if (!op_3dnow) { 4651 goto unknown_op; 4652 } 4653 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 4654 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 4655 op_3dnow(cpu_env, s->ptr0, s->ptr1); 4656 return; 4657 } 4658 } 4659 4660 4661 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 4662 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 4663 if ((sse_op_flags & SSE_OPF_V0) && 4664 !((sse_op_flags & SSE_OPF_SCALAR) && b1 >= 2)) { 4665 if (sse_op_flags & SSE_OPF_SHUF) { 4666 val = x86_ldub_code(env, s); 4667 sse_op_fn.op1i(s->ptr0, s->ptr1, tcg_const_i32(val)); 4668 } else if (b == 0xf7) { 4669 /* maskmov : we must prepare A0 */ 4670 if (mod != 3) { 4671 goto illegal_op; 4672 } 4673 tcg_gen_mov_tl(s->A0, cpu_regs[R_EDI]); 4674 gen_extu(s->aflag, s->A0); 4675 gen_add_A0_ds_seg(s); 4676 4677 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); 4678 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); 4679 sse_op_fn.op1t(cpu_env, s->ptr0, s->ptr1, s->A0); 4680 /* Does not write to the fist operand */ 4681 return; 4682 } else { 4683 sse_op_fn.op1(cpu_env, s->ptr0, s->ptr1); 4684 } 4685 } else { 4686 tcg_gen_addi_ptr(s->ptr2, cpu_env, op1_offset); 4687 if (sse_op_flags & SSE_OPF_SHUF) { 4688 val = x86_ldub_code(env, s); 4689 sse_op_fn.op2i(s->ptr0, s->ptr2, s->ptr1, 4690 tcg_const_i32(val)); 4691 } else { 4692 SSEFunc_0_eppp fn = sse_op_fn.op2; 4693 if (b == 0xc2) { 4694 /* compare insns */ 4695 val = x86_ldub_code(env, s) & 7; 4696 fn = sse_op_table4[val][b1]; 4697 } 4698 fn(cpu_env, s->ptr0, s->ptr2, s->ptr1); 4699 } 4700 } 4701 4702 if (sse_op_flags & SSE_OPF_CMP) { 4703 set_cc_op(s, CC_OP_EFLAGS); 4704 } 4705 } 4706 } 4707 4708 /* convert one instruction. s->base.is_jmp is set if the translation must 4709 be stopped. Return the next pc value */ 4710 static bool disas_insn(DisasContext *s, CPUState *cpu) 4711 { 4712 CPUX86State *env = cpu->env_ptr; 4713 int b, prefixes; 4714 int shift; 4715 MemOp ot, aflag, dflag; 4716 int modrm, reg, rm, mod, op, opreg, val; 4717 bool orig_cc_op_dirty = s->cc_op_dirty; 4718 CCOp orig_cc_op = s->cc_op; 4719 target_ulong orig_pc_save = s->pc_save; 4720 4721 s->pc = s->base.pc_next; 4722 s->override = -1; 4723 #ifdef TARGET_X86_64 4724 s->rex_r = 0; 4725 s->rex_x = 0; 4726 s->rex_b = 0; 4727 #endif 4728 s->rip_offset = 0; /* for relative ip address */ 4729 s->vex_l = 0; 4730 s->vex_v = 0; 4731 s->vex_w = false; 4732 switch (sigsetjmp(s->jmpbuf, 0)) { 4733 case 0: 4734 break; 4735 case 1: 4736 gen_exception_gpf(s); 4737 return true; 4738 case 2: 4739 /* Restore state that may affect the next instruction. */ 4740 s->pc = s->base.pc_next; 4741 /* 4742 * TODO: These save/restore can be removed after the table-based 4743 * decoder is complete; we will be decoding the insn completely 4744 * before any code generation that might affect these variables. 4745 */ 4746 s->cc_op_dirty = orig_cc_op_dirty; 4747 s->cc_op = orig_cc_op; 4748 s->pc_save = orig_pc_save; 4749 /* END TODO */ 4750 s->base.num_insns--; 4751 tcg_remove_ops_after(s->prev_insn_end); 4752 s->base.is_jmp = DISAS_TOO_MANY; 4753 return false; 4754 default: 4755 g_assert_not_reached(); 4756 } 4757 4758 prefixes = 0; 4759 4760 if (first) first = false, limit = getenv("LIMIT") ? atol(getenv("LIMIT")) : -1; 4761 bool use_new = true; 4762 #ifdef CONFIG_USER_ONLY 4763 use_new &= limit > 0; 4764 #endif 4765 next_byte: 4766 s->prefix = prefixes; 4767 b = x86_ldub_code(env, s); 4768 /* Collect prefixes. */ 4769 switch (b) { 4770 default: 4771 #ifndef CONFIG_USER_ONLY 4772 use_new &= b <= limit; 4773 #endif 4774 if (use_new && 0) { 4775 disas_insn_new(s, cpu, b); 4776 return s->pc; 4777 } 4778 break; 4779 case 0x0f: 4780 b = x86_ldub_code(env, s) + 0x100; 4781 #ifndef CONFIG_USER_ONLY 4782 use_new &= b <= limit; 4783 #endif 4784 if (use_new && 4785 ((b >= 0x150 && b <= 0x17f) || 4786 (b >= 0x1d0 && b <= 0x1ff))) { 4787 disas_insn_new(s, cpu, b + 0x100); 4788 return s->pc; 4789 } 4790 break; 4791 case 0xf3: 4792 prefixes |= PREFIX_REPZ; 4793 prefixes &= ~PREFIX_REPNZ; 4794 goto next_byte; 4795 case 0xf2: 4796 prefixes |= PREFIX_REPNZ; 4797 prefixes &= ~PREFIX_REPZ; 4798 goto next_byte; 4799 case 0xf0: 4800 prefixes |= PREFIX_LOCK; 4801 goto next_byte; 4802 case 0x2e: 4803 s->override = R_CS; 4804 goto next_byte; 4805 case 0x36: 4806 s->override = R_SS; 4807 goto next_byte; 4808 case 0x3e: 4809 s->override = R_DS; 4810 goto next_byte; 4811 case 0x26: 4812 s->override = R_ES; 4813 goto next_byte; 4814 case 0x64: 4815 s->override = R_FS; 4816 goto next_byte; 4817 case 0x65: 4818 s->override = R_GS; 4819 goto next_byte; 4820 case 0x66: 4821 prefixes |= PREFIX_DATA; 4822 goto next_byte; 4823 case 0x67: 4824 prefixes |= PREFIX_ADR; 4825 goto next_byte; 4826 #ifdef TARGET_X86_64 4827 case 0x40 ... 0x4f: 4828 if (CODE64(s)) { 4829 /* REX prefix */ 4830 prefixes |= PREFIX_REX; 4831 s->vex_w = (b >> 3) & 1; 4832 s->rex_r = (b & 0x4) << 1; 4833 s->rex_x = (b & 0x2) << 2; 4834 s->rex_b = (b & 0x1) << 3; 4835 goto next_byte; 4836 } 4837 break; 4838 #endif 4839 case 0xc5: /* 2-byte VEX */ 4840 case 0xc4: /* 3-byte VEX */ 4841 if (CODE32(s) && !VM86(s)) { 4842 int vex2 = x86_ldub_code(env, s); 4843 s->pc--; /* rewind the advance_pc() x86_ldub_code() did */ 4844 4845 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) { 4846 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b, 4847 otherwise the instruction is LES or LDS. */ 4848 break; 4849 } 4850 disas_insn_new(s, cpu, b); 4851 return s->pc; 4852 } 4853 break; 4854 } 4855 4856 /* Post-process prefixes. */ 4857 if (CODE64(s)) { 4858 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit 4859 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence 4860 over 0x66 if both are present. */ 4861 dflag = (REX_W(s) ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32); 4862 /* In 64-bit mode, 0x67 selects 32-bit addressing. */ 4863 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64); 4864 } else { 4865 /* In 16/32-bit mode, 0x66 selects the opposite data size. */ 4866 if (CODE32(s) ^ ((prefixes & PREFIX_DATA) != 0)) { 4867 dflag = MO_32; 4868 } else { 4869 dflag = MO_16; 4870 } 4871 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */ 4872 if (CODE32(s) ^ ((prefixes & PREFIX_ADR) != 0)) { 4873 aflag = MO_32; 4874 } else { 4875 aflag = MO_16; 4876 } 4877 } 4878 4879 s->prefix = prefixes; 4880 s->aflag = aflag; 4881 s->dflag = dflag; 4882 4883 /* now check op code */ 4884 switch (b) { 4885 /**************************/ 4886 /* arith & logic */ 4887 case 0x00 ... 0x05: 4888 case 0x08 ... 0x0d: 4889 case 0x10 ... 0x15: 4890 case 0x18 ... 0x1d: 4891 case 0x20 ... 0x25: 4892 case 0x28 ... 0x2d: 4893 case 0x30 ... 0x35: 4894 case 0x38 ... 0x3d: 4895 { 4896 int op, f, val; 4897 op = (b >> 3) & 7; 4898 f = (b >> 1) & 3; 4899 4900 ot = mo_b_d(b, dflag); 4901 4902 switch(f) { 4903 case 0: /* OP Ev, Gv */ 4904 modrm = x86_ldub_code(env, s); 4905 reg = ((modrm >> 3) & 7) | REX_R(s); 4906 mod = (modrm >> 6) & 3; 4907 rm = (modrm & 7) | REX_B(s); 4908 if (mod != 3) { 4909 gen_lea_modrm(env, s, modrm); 4910 opreg = OR_TMP0; 4911 } else if (op == OP_XORL && rm == reg) { 4912 xor_zero: 4913 /* xor reg, reg optimisation */ 4914 set_cc_op(s, CC_OP_CLR); 4915 tcg_gen_movi_tl(s->T0, 0); 4916 gen_op_mov_reg_v(s, ot, reg, s->T0); 4917 break; 4918 } else { 4919 opreg = rm; 4920 } 4921 gen_op_mov_v_reg(s, ot, s->T1, reg); 4922 gen_op(s, op, ot, opreg); 4923 break; 4924 case 1: /* OP Gv, Ev */ 4925 modrm = x86_ldub_code(env, s); 4926 mod = (modrm >> 6) & 3; 4927 reg = ((modrm >> 3) & 7) | REX_R(s); 4928 rm = (modrm & 7) | REX_B(s); 4929 if (mod != 3) { 4930 gen_lea_modrm(env, s, modrm); 4931 gen_op_ld_v(s, ot, s->T1, s->A0); 4932 } else if (op == OP_XORL && rm == reg) { 4933 goto xor_zero; 4934 } else { 4935 gen_op_mov_v_reg(s, ot, s->T1, rm); 4936 } 4937 gen_op(s, op, ot, reg); 4938 break; 4939 case 2: /* OP A, Iv */ 4940 val = insn_get(env, s, ot); 4941 tcg_gen_movi_tl(s->T1, val); 4942 gen_op(s, op, ot, OR_EAX); 4943 break; 4944 } 4945 } 4946 break; 4947 4948 case 0x82: 4949 if (CODE64(s)) 4950 goto illegal_op; 4951 /* fall through */ 4952 case 0x80: /* GRP1 */ 4953 case 0x81: 4954 case 0x83: 4955 { 4956 int val; 4957 4958 ot = mo_b_d(b, dflag); 4959 4960 modrm = x86_ldub_code(env, s); 4961 mod = (modrm >> 6) & 3; 4962 rm = (modrm & 7) | REX_B(s); 4963 op = (modrm >> 3) & 7; 4964 4965 if (mod != 3) { 4966 if (b == 0x83) 4967 s->rip_offset = 1; 4968 else 4969 s->rip_offset = insn_const_size(ot); 4970 gen_lea_modrm(env, s, modrm); 4971 opreg = OR_TMP0; 4972 } else { 4973 opreg = rm; 4974 } 4975 4976 switch(b) { 4977 default: 4978 case 0x80: 4979 case 0x81: 4980 case 0x82: 4981 val = insn_get(env, s, ot); 4982 break; 4983 case 0x83: 4984 val = (int8_t)insn_get(env, s, MO_8); 4985 break; 4986 } 4987 tcg_gen_movi_tl(s->T1, val); 4988 gen_op(s, op, ot, opreg); 4989 } 4990 break; 4991 4992 /**************************/ 4993 /* inc, dec, and other misc arith */ 4994 case 0x40 ... 0x47: /* inc Gv */ 4995 ot = dflag; 4996 gen_inc(s, ot, OR_EAX + (b & 7), 1); 4997 break; 4998 case 0x48 ... 0x4f: /* dec Gv */ 4999 ot = dflag; 5000 gen_inc(s, ot, OR_EAX + (b & 7), -1); 5001 break; 5002 case 0xf6: /* GRP3 */ 5003 case 0xf7: 5004 ot = mo_b_d(b, dflag); 5005 5006 modrm = x86_ldub_code(env, s); 5007 mod = (modrm >> 6) & 3; 5008 rm = (modrm & 7) | REX_B(s); 5009 op = (modrm >> 3) & 7; 5010 if (mod != 3) { 5011 if (op == 0) { 5012 s->rip_offset = insn_const_size(ot); 5013 } 5014 gen_lea_modrm(env, s, modrm); 5015 /* For those below that handle locked memory, don't load here. */ 5016 if (!(s->prefix & PREFIX_LOCK) 5017 || op != 2) { 5018 gen_op_ld_v(s, ot, s->T0, s->A0); 5019 } 5020 } else { 5021 gen_op_mov_v_reg(s, ot, s->T0, rm); 5022 } 5023 5024 switch(op) { 5025 case 0: /* test */ 5026 val = insn_get(env, s, ot); 5027 tcg_gen_movi_tl(s->T1, val); 5028 gen_op_testl_T0_T1_cc(s); 5029 set_cc_op(s, CC_OP_LOGICB + ot); 5030 break; 5031 case 2: /* not */ 5032 if (s->prefix & PREFIX_LOCK) { 5033 if (mod == 3) { 5034 goto illegal_op; 5035 } 5036 tcg_gen_movi_tl(s->T0, ~0); 5037 tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0, 5038 s->mem_index, ot | MO_LE); 5039 } else { 5040 tcg_gen_not_tl(s->T0, s->T0); 5041 if (mod != 3) { 5042 gen_op_st_v(s, ot, s->T0, s->A0); 5043 } else { 5044 gen_op_mov_reg_v(s, ot, rm, s->T0); 5045 } 5046 } 5047 break; 5048 case 3: /* neg */ 5049 if (s->prefix & PREFIX_LOCK) { 5050 TCGLabel *label1; 5051 TCGv a0, t0, t1, t2; 5052 5053 if (mod == 3) { 5054 goto illegal_op; 5055 } 5056 a0 = tcg_temp_local_new(); 5057 t0 = tcg_temp_local_new(); 5058 label1 = gen_new_label(); 5059 5060 tcg_gen_mov_tl(a0, s->A0); 5061 tcg_gen_mov_tl(t0, s->T0); 5062 5063 gen_set_label(label1); 5064 t1 = tcg_temp_new(); 5065 t2 = tcg_temp_new(); 5066 tcg_gen_mov_tl(t2, t0); 5067 tcg_gen_neg_tl(t1, t0); 5068 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1, 5069 s->mem_index, ot | MO_LE); 5070 tcg_temp_free(t1); 5071 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1); 5072 5073 tcg_temp_free(t2); 5074 tcg_temp_free(a0); 5075 tcg_gen_mov_tl(s->T0, t0); 5076 tcg_temp_free(t0); 5077 } else { 5078 tcg_gen_neg_tl(s->T0, s->T0); 5079 if (mod != 3) { 5080 gen_op_st_v(s, ot, s->T0, s->A0); 5081 } else { 5082 gen_op_mov_reg_v(s, ot, rm, s->T0); 5083 } 5084 } 5085 gen_op_update_neg_cc(s); 5086 set_cc_op(s, CC_OP_SUBB + ot); 5087 break; 5088 case 4: /* mul */ 5089 switch(ot) { 5090 case MO_8: 5091 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX); 5092 tcg_gen_ext8u_tl(s->T0, s->T0); 5093 tcg_gen_ext8u_tl(s->T1, s->T1); 5094 /* XXX: use 32 bit mul which could be faster */ 5095 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 5096 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 5097 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 5098 tcg_gen_andi_tl(cpu_cc_src, s->T0, 0xff00); 5099 set_cc_op(s, CC_OP_MULB); 5100 break; 5101 case MO_16: 5102 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX); 5103 tcg_gen_ext16u_tl(s->T0, s->T0); 5104 tcg_gen_ext16u_tl(s->T1, s->T1); 5105 /* XXX: use 32 bit mul which could be faster */ 5106 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 5107 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 5108 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 5109 tcg_gen_shri_tl(s->T0, s->T0, 16); 5110 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); 5111 tcg_gen_mov_tl(cpu_cc_src, s->T0); 5112 set_cc_op(s, CC_OP_MULW); 5113 break; 5114 default: 5115 case MO_32: 5116 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5117 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]); 5118 tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32, 5119 s->tmp2_i32, s->tmp3_i32); 5120 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32); 5121 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32); 5122 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 5123 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]); 5124 set_cc_op(s, CC_OP_MULL); 5125 break; 5126 #ifdef TARGET_X86_64 5127 case MO_64: 5128 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX], 5129 s->T0, cpu_regs[R_EAX]); 5130 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 5131 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]); 5132 set_cc_op(s, CC_OP_MULQ); 5133 break; 5134 #endif 5135 } 5136 break; 5137 case 5: /* imul */ 5138 switch(ot) { 5139 case MO_8: 5140 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX); 5141 tcg_gen_ext8s_tl(s->T0, s->T0); 5142 tcg_gen_ext8s_tl(s->T1, s->T1); 5143 /* XXX: use 32 bit mul which could be faster */ 5144 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 5145 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 5146 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 5147 tcg_gen_ext8s_tl(s->tmp0, s->T0); 5148 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0); 5149 set_cc_op(s, CC_OP_MULB); 5150 break; 5151 case MO_16: 5152 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX); 5153 tcg_gen_ext16s_tl(s->T0, s->T0); 5154 tcg_gen_ext16s_tl(s->T1, s->T1); 5155 /* XXX: use 32 bit mul which could be faster */ 5156 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 5157 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 5158 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 5159 tcg_gen_ext16s_tl(s->tmp0, s->T0); 5160 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0); 5161 tcg_gen_shri_tl(s->T0, s->T0, 16); 5162 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); 5163 set_cc_op(s, CC_OP_MULW); 5164 break; 5165 default: 5166 case MO_32: 5167 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5168 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]); 5169 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32, 5170 s->tmp2_i32, s->tmp3_i32); 5171 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32); 5172 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32); 5173 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31); 5174 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 5175 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32); 5176 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32); 5177 set_cc_op(s, CC_OP_MULL); 5178 break; 5179 #ifdef TARGET_X86_64 5180 case MO_64: 5181 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX], 5182 s->T0, cpu_regs[R_EAX]); 5183 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 5184 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63); 5185 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]); 5186 set_cc_op(s, CC_OP_MULQ); 5187 break; 5188 #endif 5189 } 5190 break; 5191 case 6: /* div */ 5192 switch(ot) { 5193 case MO_8: 5194 gen_helper_divb_AL(cpu_env, s->T0); 5195 break; 5196 case MO_16: 5197 gen_helper_divw_AX(cpu_env, s->T0); 5198 break; 5199 default: 5200 case MO_32: 5201 gen_helper_divl_EAX(cpu_env, s->T0); 5202 break; 5203 #ifdef TARGET_X86_64 5204 case MO_64: 5205 gen_helper_divq_EAX(cpu_env, s->T0); 5206 break; 5207 #endif 5208 } 5209 break; 5210 case 7: /* idiv */ 5211 switch(ot) { 5212 case MO_8: 5213 gen_helper_idivb_AL(cpu_env, s->T0); 5214 break; 5215 case MO_16: 5216 gen_helper_idivw_AX(cpu_env, s->T0); 5217 break; 5218 default: 5219 case MO_32: 5220 gen_helper_idivl_EAX(cpu_env, s->T0); 5221 break; 5222 #ifdef TARGET_X86_64 5223 case MO_64: 5224 gen_helper_idivq_EAX(cpu_env, s->T0); 5225 break; 5226 #endif 5227 } 5228 break; 5229 default: 5230 goto unknown_op; 5231 } 5232 break; 5233 5234 case 0xfe: /* GRP4 */ 5235 case 0xff: /* GRP5 */ 5236 ot = mo_b_d(b, dflag); 5237 5238 modrm = x86_ldub_code(env, s); 5239 mod = (modrm >> 6) & 3; 5240 rm = (modrm & 7) | REX_B(s); 5241 op = (modrm >> 3) & 7; 5242 if (op >= 2 && b == 0xfe) { 5243 goto unknown_op; 5244 } 5245 if (CODE64(s)) { 5246 if (op == 2 || op == 4) { 5247 /* operand size for jumps is 64 bit */ 5248 ot = MO_64; 5249 } else if (op == 3 || op == 5) { 5250 ot = dflag != MO_16 ? MO_32 + REX_W(s) : MO_16; 5251 } else if (op == 6) { 5252 /* default push size is 64 bit */ 5253 ot = mo_pushpop(s, dflag); 5254 } 5255 } 5256 if (mod != 3) { 5257 gen_lea_modrm(env, s, modrm); 5258 if (op >= 2 && op != 3 && op != 5) 5259 gen_op_ld_v(s, ot, s->T0, s->A0); 5260 } else { 5261 gen_op_mov_v_reg(s, ot, s->T0, rm); 5262 } 5263 5264 switch(op) { 5265 case 0: /* inc Ev */ 5266 if (mod != 3) 5267 opreg = OR_TMP0; 5268 else 5269 opreg = rm; 5270 gen_inc(s, ot, opreg, 1); 5271 break; 5272 case 1: /* dec Ev */ 5273 if (mod != 3) 5274 opreg = OR_TMP0; 5275 else 5276 opreg = rm; 5277 gen_inc(s, ot, opreg, -1); 5278 break; 5279 case 2: /* call Ev */ 5280 /* XXX: optimize if memory (no 'and' is necessary) */ 5281 if (dflag == MO_16) { 5282 tcg_gen_ext16u_tl(s->T0, s->T0); 5283 } 5284 gen_push_v(s, eip_next_tl(s)); 5285 gen_op_jmp_v(s, s->T0); 5286 gen_bnd_jmp(s); 5287 s->base.is_jmp = DISAS_JUMP; 5288 break; 5289 case 3: /* lcall Ev */ 5290 if (mod == 3) { 5291 goto illegal_op; 5292 } 5293 gen_op_ld_v(s, ot, s->T1, s->A0); 5294 gen_add_A0_im(s, 1 << ot); 5295 gen_op_ld_v(s, MO_16, s->T0, s->A0); 5296 do_lcall: 5297 if (PE(s) && !VM86(s)) { 5298 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5299 gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1, 5300 tcg_constant_i32(dflag - 1), 5301 eip_next_tl(s)); 5302 } else { 5303 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5304 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 5305 gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32, 5306 tcg_constant_i32(dflag - 1), 5307 eip_next_i32(s)); 5308 } 5309 s->base.is_jmp = DISAS_JUMP; 5310 break; 5311 case 4: /* jmp Ev */ 5312 if (dflag == MO_16) { 5313 tcg_gen_ext16u_tl(s->T0, s->T0); 5314 } 5315 gen_op_jmp_v(s, s->T0); 5316 gen_bnd_jmp(s); 5317 s->base.is_jmp = DISAS_JUMP; 5318 break; 5319 case 5: /* ljmp Ev */ 5320 if (mod == 3) { 5321 goto illegal_op; 5322 } 5323 gen_op_ld_v(s, ot, s->T1, s->A0); 5324 gen_add_A0_im(s, 1 << ot); 5325 gen_op_ld_v(s, MO_16, s->T0, s->A0); 5326 do_ljmp: 5327 if (PE(s) && !VM86(s)) { 5328 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5329 gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1, 5330 eip_next_tl(s)); 5331 } else { 5332 gen_op_movl_seg_T0_vm(s, R_CS); 5333 gen_op_jmp_v(s, s->T1); 5334 } 5335 s->base.is_jmp = DISAS_JUMP; 5336 break; 5337 case 6: /* push Ev */ 5338 gen_push_v(s, s->T0); 5339 break; 5340 default: 5341 goto unknown_op; 5342 } 5343 break; 5344 5345 case 0x84: /* test Ev, Gv */ 5346 case 0x85: 5347 ot = mo_b_d(b, dflag); 5348 5349 modrm = x86_ldub_code(env, s); 5350 reg = ((modrm >> 3) & 7) | REX_R(s); 5351 5352 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 5353 gen_op_mov_v_reg(s, ot, s->T1, reg); 5354 gen_op_testl_T0_T1_cc(s); 5355 set_cc_op(s, CC_OP_LOGICB + ot); 5356 break; 5357 5358 case 0xa8: /* test eAX, Iv */ 5359 case 0xa9: 5360 ot = mo_b_d(b, dflag); 5361 val = insn_get(env, s, ot); 5362 5363 gen_op_mov_v_reg(s, ot, s->T0, OR_EAX); 5364 tcg_gen_movi_tl(s->T1, val); 5365 gen_op_testl_T0_T1_cc(s); 5366 set_cc_op(s, CC_OP_LOGICB + ot); 5367 break; 5368 5369 case 0x98: /* CWDE/CBW */ 5370 switch (dflag) { 5371 #ifdef TARGET_X86_64 5372 case MO_64: 5373 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX); 5374 tcg_gen_ext32s_tl(s->T0, s->T0); 5375 gen_op_mov_reg_v(s, MO_64, R_EAX, s->T0); 5376 break; 5377 #endif 5378 case MO_32: 5379 gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX); 5380 tcg_gen_ext16s_tl(s->T0, s->T0); 5381 gen_op_mov_reg_v(s, MO_32, R_EAX, s->T0); 5382 break; 5383 case MO_16: 5384 gen_op_mov_v_reg(s, MO_8, s->T0, R_EAX); 5385 tcg_gen_ext8s_tl(s->T0, s->T0); 5386 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 5387 break; 5388 default: 5389 tcg_abort(); 5390 } 5391 break; 5392 case 0x99: /* CDQ/CWD */ 5393 switch (dflag) { 5394 #ifdef TARGET_X86_64 5395 case MO_64: 5396 gen_op_mov_v_reg(s, MO_64, s->T0, R_EAX); 5397 tcg_gen_sari_tl(s->T0, s->T0, 63); 5398 gen_op_mov_reg_v(s, MO_64, R_EDX, s->T0); 5399 break; 5400 #endif 5401 case MO_32: 5402 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX); 5403 tcg_gen_ext32s_tl(s->T0, s->T0); 5404 tcg_gen_sari_tl(s->T0, s->T0, 31); 5405 gen_op_mov_reg_v(s, MO_32, R_EDX, s->T0); 5406 break; 5407 case MO_16: 5408 gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX); 5409 tcg_gen_ext16s_tl(s->T0, s->T0); 5410 tcg_gen_sari_tl(s->T0, s->T0, 15); 5411 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); 5412 break; 5413 default: 5414 tcg_abort(); 5415 } 5416 break; 5417 case 0x1af: /* imul Gv, Ev */ 5418 case 0x69: /* imul Gv, Ev, I */ 5419 case 0x6b: 5420 ot = dflag; 5421 modrm = x86_ldub_code(env, s); 5422 reg = ((modrm >> 3) & 7) | REX_R(s); 5423 if (b == 0x69) 5424 s->rip_offset = insn_const_size(ot); 5425 else if (b == 0x6b) 5426 s->rip_offset = 1; 5427 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 5428 if (b == 0x69) { 5429 val = insn_get(env, s, ot); 5430 tcg_gen_movi_tl(s->T1, val); 5431 } else if (b == 0x6b) { 5432 val = (int8_t)insn_get(env, s, MO_8); 5433 tcg_gen_movi_tl(s->T1, val); 5434 } else { 5435 gen_op_mov_v_reg(s, ot, s->T1, reg); 5436 } 5437 switch (ot) { 5438 #ifdef TARGET_X86_64 5439 case MO_64: 5440 tcg_gen_muls2_i64(cpu_regs[reg], s->T1, s->T0, s->T1); 5441 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]); 5442 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63); 5443 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, s->T1); 5444 break; 5445 #endif 5446 case MO_32: 5447 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5448 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 5449 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32, 5450 s->tmp2_i32, s->tmp3_i32); 5451 tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32); 5452 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31); 5453 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]); 5454 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32); 5455 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32); 5456 break; 5457 default: 5458 tcg_gen_ext16s_tl(s->T0, s->T0); 5459 tcg_gen_ext16s_tl(s->T1, s->T1); 5460 /* XXX: use 32 bit mul which could be faster */ 5461 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 5462 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 5463 tcg_gen_ext16s_tl(s->tmp0, s->T0); 5464 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0); 5465 gen_op_mov_reg_v(s, ot, reg, s->T0); 5466 break; 5467 } 5468 set_cc_op(s, CC_OP_MULB + ot); 5469 break; 5470 case 0x1c0: 5471 case 0x1c1: /* xadd Ev, Gv */ 5472 ot = mo_b_d(b, dflag); 5473 modrm = x86_ldub_code(env, s); 5474 reg = ((modrm >> 3) & 7) | REX_R(s); 5475 mod = (modrm >> 6) & 3; 5476 gen_op_mov_v_reg(s, ot, s->T0, reg); 5477 if (mod == 3) { 5478 rm = (modrm & 7) | REX_B(s); 5479 gen_op_mov_v_reg(s, ot, s->T1, rm); 5480 tcg_gen_add_tl(s->T0, s->T0, s->T1); 5481 gen_op_mov_reg_v(s, ot, reg, s->T1); 5482 gen_op_mov_reg_v(s, ot, rm, s->T0); 5483 } else { 5484 gen_lea_modrm(env, s, modrm); 5485 if (s->prefix & PREFIX_LOCK) { 5486 tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0, 5487 s->mem_index, ot | MO_LE); 5488 tcg_gen_add_tl(s->T0, s->T0, s->T1); 5489 } else { 5490 gen_op_ld_v(s, ot, s->T1, s->A0); 5491 tcg_gen_add_tl(s->T0, s->T0, s->T1); 5492 gen_op_st_v(s, ot, s->T0, s->A0); 5493 } 5494 gen_op_mov_reg_v(s, ot, reg, s->T1); 5495 } 5496 gen_op_update2_cc(s); 5497 set_cc_op(s, CC_OP_ADDB + ot); 5498 break; 5499 case 0x1b0: 5500 case 0x1b1: /* cmpxchg Ev, Gv */ 5501 { 5502 TCGv oldv, newv, cmpv; 5503 5504 ot = mo_b_d(b, dflag); 5505 modrm = x86_ldub_code(env, s); 5506 reg = ((modrm >> 3) & 7) | REX_R(s); 5507 mod = (modrm >> 6) & 3; 5508 oldv = tcg_temp_new(); 5509 newv = tcg_temp_new(); 5510 cmpv = tcg_temp_new(); 5511 gen_op_mov_v_reg(s, ot, newv, reg); 5512 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]); 5513 5514 if (s->prefix & PREFIX_LOCK) { 5515 if (mod == 3) { 5516 goto illegal_op; 5517 } 5518 gen_lea_modrm(env, s, modrm); 5519 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv, 5520 s->mem_index, ot | MO_LE); 5521 gen_op_mov_reg_v(s, ot, R_EAX, oldv); 5522 } else { 5523 if (mod == 3) { 5524 rm = (modrm & 7) | REX_B(s); 5525 gen_op_mov_v_reg(s, ot, oldv, rm); 5526 } else { 5527 gen_lea_modrm(env, s, modrm); 5528 gen_op_ld_v(s, ot, oldv, s->A0); 5529 rm = 0; /* avoid warning */ 5530 } 5531 gen_extu(ot, oldv); 5532 gen_extu(ot, cmpv); 5533 /* store value = (old == cmp ? new : old); */ 5534 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv); 5535 if (mod == 3) { 5536 gen_op_mov_reg_v(s, ot, R_EAX, oldv); 5537 gen_op_mov_reg_v(s, ot, rm, newv); 5538 } else { 5539 /* Perform an unconditional store cycle like physical cpu; 5540 must be before changing accumulator to ensure 5541 idempotency if the store faults and the instruction 5542 is restarted */ 5543 gen_op_st_v(s, ot, newv, s->A0); 5544 gen_op_mov_reg_v(s, ot, R_EAX, oldv); 5545 } 5546 } 5547 tcg_gen_mov_tl(cpu_cc_src, oldv); 5548 tcg_gen_mov_tl(s->cc_srcT, cmpv); 5549 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv); 5550 set_cc_op(s, CC_OP_SUBB + ot); 5551 tcg_temp_free(oldv); 5552 tcg_temp_free(newv); 5553 tcg_temp_free(cmpv); 5554 } 5555 break; 5556 case 0x1c7: /* cmpxchg8b */ 5557 modrm = x86_ldub_code(env, s); 5558 mod = (modrm >> 6) & 3; 5559 switch ((modrm >> 3) & 7) { 5560 case 1: /* CMPXCHG8, CMPXCHG16 */ 5561 if (mod == 3) { 5562 goto illegal_op; 5563 } 5564 #ifdef TARGET_X86_64 5565 if (dflag == MO_64) { 5566 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) { 5567 goto illegal_op; 5568 } 5569 gen_lea_modrm(env, s, modrm); 5570 if ((s->prefix & PREFIX_LOCK) && 5571 (tb_cflags(s->base.tb) & CF_PARALLEL)) { 5572 gen_helper_cmpxchg16b(cpu_env, s->A0); 5573 } else { 5574 gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0); 5575 } 5576 set_cc_op(s, CC_OP_EFLAGS); 5577 break; 5578 } 5579 #endif 5580 if (!(s->cpuid_features & CPUID_CX8)) { 5581 goto illegal_op; 5582 } 5583 gen_lea_modrm(env, s, modrm); 5584 if ((s->prefix & PREFIX_LOCK) && 5585 (tb_cflags(s->base.tb) & CF_PARALLEL)) { 5586 gen_helper_cmpxchg8b(cpu_env, s->A0); 5587 } else { 5588 gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0); 5589 } 5590 set_cc_op(s, CC_OP_EFLAGS); 5591 break; 5592 5593 case 7: /* RDSEED */ 5594 case 6: /* RDRAND */ 5595 if (mod != 3 || 5596 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) || 5597 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { 5598 goto illegal_op; 5599 } 5600 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 5601 gen_io_start(); 5602 s->base.is_jmp = DISAS_TOO_MANY; 5603 } 5604 gen_helper_rdrand(s->T0, cpu_env); 5605 rm = (modrm & 7) | REX_B(s); 5606 gen_op_mov_reg_v(s, dflag, rm, s->T0); 5607 set_cc_op(s, CC_OP_EFLAGS); 5608 break; 5609 5610 default: 5611 goto illegal_op; 5612 } 5613 break; 5614 5615 /**************************/ 5616 /* push/pop */ 5617 case 0x50 ... 0x57: /* push */ 5618 gen_op_mov_v_reg(s, MO_32, s->T0, (b & 7) | REX_B(s)); 5619 gen_push_v(s, s->T0); 5620 break; 5621 case 0x58 ... 0x5f: /* pop */ 5622 ot = gen_pop_T0(s); 5623 /* NOTE: order is important for pop %sp */ 5624 gen_pop_update(s, ot); 5625 gen_op_mov_reg_v(s, ot, (b & 7) | REX_B(s), s->T0); 5626 break; 5627 case 0x60: /* pusha */ 5628 if (CODE64(s)) 5629 goto illegal_op; 5630 gen_pusha(s); 5631 break; 5632 case 0x61: /* popa */ 5633 if (CODE64(s)) 5634 goto illegal_op; 5635 gen_popa(s); 5636 break; 5637 case 0x68: /* push Iv */ 5638 case 0x6a: 5639 ot = mo_pushpop(s, dflag); 5640 if (b == 0x68) 5641 val = insn_get(env, s, ot); 5642 else 5643 val = (int8_t)insn_get(env, s, MO_8); 5644 tcg_gen_movi_tl(s->T0, val); 5645 gen_push_v(s, s->T0); 5646 break; 5647 case 0x8f: /* pop Ev */ 5648 modrm = x86_ldub_code(env, s); 5649 mod = (modrm >> 6) & 3; 5650 ot = gen_pop_T0(s); 5651 if (mod == 3) { 5652 /* NOTE: order is important for pop %sp */ 5653 gen_pop_update(s, ot); 5654 rm = (modrm & 7) | REX_B(s); 5655 gen_op_mov_reg_v(s, ot, rm, s->T0); 5656 } else { 5657 /* NOTE: order is important too for MMU exceptions */ 5658 s->popl_esp_hack = 1 << ot; 5659 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 5660 s->popl_esp_hack = 0; 5661 gen_pop_update(s, ot); 5662 } 5663 break; 5664 case 0xc8: /* enter */ 5665 { 5666 int level; 5667 val = x86_lduw_code(env, s); 5668 level = x86_ldub_code(env, s); 5669 gen_enter(s, val, level); 5670 } 5671 break; 5672 case 0xc9: /* leave */ 5673 gen_leave(s); 5674 break; 5675 case 0x06: /* push es */ 5676 case 0x0e: /* push cs */ 5677 case 0x16: /* push ss */ 5678 case 0x1e: /* push ds */ 5679 if (CODE64(s)) 5680 goto illegal_op; 5681 gen_op_movl_T0_seg(s, b >> 3); 5682 gen_push_v(s, s->T0); 5683 break; 5684 case 0x1a0: /* push fs */ 5685 case 0x1a8: /* push gs */ 5686 gen_op_movl_T0_seg(s, (b >> 3) & 7); 5687 gen_push_v(s, s->T0); 5688 break; 5689 case 0x07: /* pop es */ 5690 case 0x17: /* pop ss */ 5691 case 0x1f: /* pop ds */ 5692 if (CODE64(s)) 5693 goto illegal_op; 5694 reg = b >> 3; 5695 ot = gen_pop_T0(s); 5696 gen_movl_seg_T0(s, reg); 5697 gen_pop_update(s, ot); 5698 break; 5699 case 0x1a1: /* pop fs */ 5700 case 0x1a9: /* pop gs */ 5701 ot = gen_pop_T0(s); 5702 gen_movl_seg_T0(s, (b >> 3) & 7); 5703 gen_pop_update(s, ot); 5704 break; 5705 5706 /**************************/ 5707 /* mov */ 5708 case 0x88: 5709 case 0x89: /* mov Gv, Ev */ 5710 ot = mo_b_d(b, dflag); 5711 modrm = x86_ldub_code(env, s); 5712 reg = ((modrm >> 3) & 7) | REX_R(s); 5713 5714 /* generate a generic store */ 5715 gen_ldst_modrm(env, s, modrm, ot, reg, 1); 5716 break; 5717 case 0xc6: 5718 case 0xc7: /* mov Ev, Iv */ 5719 ot = mo_b_d(b, dflag); 5720 modrm = x86_ldub_code(env, s); 5721 mod = (modrm >> 6) & 3; 5722 if (mod != 3) { 5723 s->rip_offset = insn_const_size(ot); 5724 gen_lea_modrm(env, s, modrm); 5725 } 5726 val = insn_get(env, s, ot); 5727 tcg_gen_movi_tl(s->T0, val); 5728 if (mod != 3) { 5729 gen_op_st_v(s, ot, s->T0, s->A0); 5730 } else { 5731 gen_op_mov_reg_v(s, ot, (modrm & 7) | REX_B(s), s->T0); 5732 } 5733 break; 5734 case 0x8a: 5735 case 0x8b: /* mov Ev, Gv */ 5736 ot = mo_b_d(b, dflag); 5737 modrm = x86_ldub_code(env, s); 5738 reg = ((modrm >> 3) & 7) | REX_R(s); 5739 5740 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 5741 gen_op_mov_reg_v(s, ot, reg, s->T0); 5742 break; 5743 case 0x8e: /* mov seg, Gv */ 5744 modrm = x86_ldub_code(env, s); 5745 reg = (modrm >> 3) & 7; 5746 if (reg >= 6 || reg == R_CS) 5747 goto illegal_op; 5748 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 5749 gen_movl_seg_T0(s, reg); 5750 break; 5751 case 0x8c: /* mov Gv, seg */ 5752 modrm = x86_ldub_code(env, s); 5753 reg = (modrm >> 3) & 7; 5754 mod = (modrm >> 6) & 3; 5755 if (reg >= 6) 5756 goto illegal_op; 5757 gen_op_movl_T0_seg(s, reg); 5758 ot = mod == 3 ? dflag : MO_16; 5759 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 5760 break; 5761 5762 case 0x1b6: /* movzbS Gv, Eb */ 5763 case 0x1b7: /* movzwS Gv, Eb */ 5764 case 0x1be: /* movsbS Gv, Eb */ 5765 case 0x1bf: /* movswS Gv, Eb */ 5766 { 5767 MemOp d_ot; 5768 MemOp s_ot; 5769 5770 /* d_ot is the size of destination */ 5771 d_ot = dflag; 5772 /* ot is the size of source */ 5773 ot = (b & 1) + MO_8; 5774 /* s_ot is the sign+size of source */ 5775 s_ot = b & 8 ? MO_SIGN | ot : ot; 5776 5777 modrm = x86_ldub_code(env, s); 5778 reg = ((modrm >> 3) & 7) | REX_R(s); 5779 mod = (modrm >> 6) & 3; 5780 rm = (modrm & 7) | REX_B(s); 5781 5782 if (mod == 3) { 5783 if (s_ot == MO_SB && byte_reg_is_xH(s, rm)) { 5784 tcg_gen_sextract_tl(s->T0, cpu_regs[rm - 4], 8, 8); 5785 } else { 5786 gen_op_mov_v_reg(s, ot, s->T0, rm); 5787 switch (s_ot) { 5788 case MO_UB: 5789 tcg_gen_ext8u_tl(s->T0, s->T0); 5790 break; 5791 case MO_SB: 5792 tcg_gen_ext8s_tl(s->T0, s->T0); 5793 break; 5794 case MO_UW: 5795 tcg_gen_ext16u_tl(s->T0, s->T0); 5796 break; 5797 default: 5798 case MO_SW: 5799 tcg_gen_ext16s_tl(s->T0, s->T0); 5800 break; 5801 } 5802 } 5803 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 5804 } else { 5805 gen_lea_modrm(env, s, modrm); 5806 gen_op_ld_v(s, s_ot, s->T0, s->A0); 5807 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 5808 } 5809 } 5810 break; 5811 5812 case 0x8d: /* lea */ 5813 modrm = x86_ldub_code(env, s); 5814 mod = (modrm >> 6) & 3; 5815 if (mod == 3) 5816 goto illegal_op; 5817 reg = ((modrm >> 3) & 7) | REX_R(s); 5818 { 5819 AddressParts a = gen_lea_modrm_0(env, s, modrm); 5820 TCGv ea = gen_lea_modrm_1(s, a, false); 5821 gen_lea_v_seg(s, s->aflag, ea, -1, -1); 5822 gen_op_mov_reg_v(s, dflag, reg, s->A0); 5823 } 5824 break; 5825 5826 case 0xa0: /* mov EAX, Ov */ 5827 case 0xa1: 5828 case 0xa2: /* mov Ov, EAX */ 5829 case 0xa3: 5830 { 5831 target_ulong offset_addr; 5832 5833 ot = mo_b_d(b, dflag); 5834 offset_addr = insn_get_addr(env, s, s->aflag); 5835 tcg_gen_movi_tl(s->A0, offset_addr); 5836 gen_add_A0_ds_seg(s); 5837 if ((b & 2) == 0) { 5838 gen_op_ld_v(s, ot, s->T0, s->A0); 5839 gen_op_mov_reg_v(s, ot, R_EAX, s->T0); 5840 } else { 5841 gen_op_mov_v_reg(s, ot, s->T0, R_EAX); 5842 gen_op_st_v(s, ot, s->T0, s->A0); 5843 } 5844 } 5845 break; 5846 case 0xd7: /* xlat */ 5847 tcg_gen_mov_tl(s->A0, cpu_regs[R_EBX]); 5848 tcg_gen_ext8u_tl(s->T0, cpu_regs[R_EAX]); 5849 tcg_gen_add_tl(s->A0, s->A0, s->T0); 5850 gen_extu(s->aflag, s->A0); 5851 gen_add_A0_ds_seg(s); 5852 gen_op_ld_v(s, MO_8, s->T0, s->A0); 5853 gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0); 5854 break; 5855 case 0xb0 ... 0xb7: /* mov R, Ib */ 5856 val = insn_get(env, s, MO_8); 5857 tcg_gen_movi_tl(s->T0, val); 5858 gen_op_mov_reg_v(s, MO_8, (b & 7) | REX_B(s), s->T0); 5859 break; 5860 case 0xb8 ... 0xbf: /* mov R, Iv */ 5861 #ifdef TARGET_X86_64 5862 if (dflag == MO_64) { 5863 uint64_t tmp; 5864 /* 64 bit case */ 5865 tmp = x86_ldq_code(env, s); 5866 reg = (b & 7) | REX_B(s); 5867 tcg_gen_movi_tl(s->T0, tmp); 5868 gen_op_mov_reg_v(s, MO_64, reg, s->T0); 5869 } else 5870 #endif 5871 { 5872 ot = dflag; 5873 val = insn_get(env, s, ot); 5874 reg = (b & 7) | REX_B(s); 5875 tcg_gen_movi_tl(s->T0, val); 5876 gen_op_mov_reg_v(s, ot, reg, s->T0); 5877 } 5878 break; 5879 5880 case 0x91 ... 0x97: /* xchg R, EAX */ 5881 do_xchg_reg_eax: 5882 ot = dflag; 5883 reg = (b & 7) | REX_B(s); 5884 rm = R_EAX; 5885 goto do_xchg_reg; 5886 case 0x86: 5887 case 0x87: /* xchg Ev, Gv */ 5888 ot = mo_b_d(b, dflag); 5889 modrm = x86_ldub_code(env, s); 5890 reg = ((modrm >> 3) & 7) | REX_R(s); 5891 mod = (modrm >> 6) & 3; 5892 if (mod == 3) { 5893 rm = (modrm & 7) | REX_B(s); 5894 do_xchg_reg: 5895 gen_op_mov_v_reg(s, ot, s->T0, reg); 5896 gen_op_mov_v_reg(s, ot, s->T1, rm); 5897 gen_op_mov_reg_v(s, ot, rm, s->T0); 5898 gen_op_mov_reg_v(s, ot, reg, s->T1); 5899 } else { 5900 gen_lea_modrm(env, s, modrm); 5901 gen_op_mov_v_reg(s, ot, s->T0, reg); 5902 /* for xchg, lock is implicit */ 5903 tcg_gen_atomic_xchg_tl(s->T1, s->A0, s->T0, 5904 s->mem_index, ot | MO_LE); 5905 gen_op_mov_reg_v(s, ot, reg, s->T1); 5906 } 5907 break; 5908 case 0xc4: /* les Gv */ 5909 /* In CODE64 this is VEX3; see above. */ 5910 op = R_ES; 5911 goto do_lxx; 5912 case 0xc5: /* lds Gv */ 5913 /* In CODE64 this is VEX2; see above. */ 5914 op = R_DS; 5915 goto do_lxx; 5916 case 0x1b2: /* lss Gv */ 5917 op = R_SS; 5918 goto do_lxx; 5919 case 0x1b4: /* lfs Gv */ 5920 op = R_FS; 5921 goto do_lxx; 5922 case 0x1b5: /* lgs Gv */ 5923 op = R_GS; 5924 do_lxx: 5925 ot = dflag != MO_16 ? MO_32 : MO_16; 5926 modrm = x86_ldub_code(env, s); 5927 reg = ((modrm >> 3) & 7) | REX_R(s); 5928 mod = (modrm >> 6) & 3; 5929 if (mod == 3) 5930 goto illegal_op; 5931 gen_lea_modrm(env, s, modrm); 5932 gen_op_ld_v(s, ot, s->T1, s->A0); 5933 gen_add_A0_im(s, 1 << ot); 5934 /* load the segment first to handle exceptions properly */ 5935 gen_op_ld_v(s, MO_16, s->T0, s->A0); 5936 gen_movl_seg_T0(s, op); 5937 /* then put the data */ 5938 gen_op_mov_reg_v(s, ot, reg, s->T1); 5939 break; 5940 5941 /************************/ 5942 /* shifts */ 5943 case 0xc0: 5944 case 0xc1: 5945 /* shift Ev,Ib */ 5946 shift = 2; 5947 grp2: 5948 { 5949 ot = mo_b_d(b, dflag); 5950 modrm = x86_ldub_code(env, s); 5951 mod = (modrm >> 6) & 3; 5952 op = (modrm >> 3) & 7; 5953 5954 if (mod != 3) { 5955 if (shift == 2) { 5956 s->rip_offset = 1; 5957 } 5958 gen_lea_modrm(env, s, modrm); 5959 opreg = OR_TMP0; 5960 } else { 5961 opreg = (modrm & 7) | REX_B(s); 5962 } 5963 5964 /* simpler op */ 5965 if (shift == 0) { 5966 gen_shift(s, op, ot, opreg, OR_ECX); 5967 } else { 5968 if (shift == 2) { 5969 shift = x86_ldub_code(env, s); 5970 } 5971 gen_shifti(s, op, ot, opreg, shift); 5972 } 5973 } 5974 break; 5975 case 0xd0: 5976 case 0xd1: 5977 /* shift Ev,1 */ 5978 shift = 1; 5979 goto grp2; 5980 case 0xd2: 5981 case 0xd3: 5982 /* shift Ev,cl */ 5983 shift = 0; 5984 goto grp2; 5985 5986 case 0x1a4: /* shld imm */ 5987 op = 0; 5988 shift = 1; 5989 goto do_shiftd; 5990 case 0x1a5: /* shld cl */ 5991 op = 0; 5992 shift = 0; 5993 goto do_shiftd; 5994 case 0x1ac: /* shrd imm */ 5995 op = 1; 5996 shift = 1; 5997 goto do_shiftd; 5998 case 0x1ad: /* shrd cl */ 5999 op = 1; 6000 shift = 0; 6001 do_shiftd: 6002 ot = dflag; 6003 modrm = x86_ldub_code(env, s); 6004 mod = (modrm >> 6) & 3; 6005 rm = (modrm & 7) | REX_B(s); 6006 reg = ((modrm >> 3) & 7) | REX_R(s); 6007 if (mod != 3) { 6008 gen_lea_modrm(env, s, modrm); 6009 opreg = OR_TMP0; 6010 } else { 6011 opreg = rm; 6012 } 6013 gen_op_mov_v_reg(s, ot, s->T1, reg); 6014 6015 if (shift) { 6016 TCGv imm = tcg_const_tl(x86_ldub_code(env, s)); 6017 gen_shiftd_rm_T1(s, ot, opreg, op, imm); 6018 tcg_temp_free(imm); 6019 } else { 6020 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]); 6021 } 6022 break; 6023 6024 /************************/ 6025 /* floats */ 6026 case 0xd8 ... 0xdf: 6027 { 6028 bool update_fip = true; 6029 6030 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 6031 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 6032 /* XXX: what to do if illegal op ? */ 6033 gen_exception(s, EXCP07_PREX); 6034 break; 6035 } 6036 modrm = x86_ldub_code(env, s); 6037 mod = (modrm >> 6) & 3; 6038 rm = modrm & 7; 6039 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 6040 if (mod != 3) { 6041 /* memory op */ 6042 AddressParts a = gen_lea_modrm_0(env, s, modrm); 6043 TCGv ea = gen_lea_modrm_1(s, a, false); 6044 TCGv last_addr = tcg_temp_new(); 6045 bool update_fdp = true; 6046 6047 tcg_gen_mov_tl(last_addr, ea); 6048 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override); 6049 6050 switch (op) { 6051 case 0x00 ... 0x07: /* fxxxs */ 6052 case 0x10 ... 0x17: /* fixxxl */ 6053 case 0x20 ... 0x27: /* fxxxl */ 6054 case 0x30 ... 0x37: /* fixxx */ 6055 { 6056 int op1; 6057 op1 = op & 7; 6058 6059 switch (op >> 4) { 6060 case 0: 6061 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 6062 s->mem_index, MO_LEUL); 6063 gen_helper_flds_FT0(cpu_env, s->tmp2_i32); 6064 break; 6065 case 1: 6066 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 6067 s->mem_index, MO_LEUL); 6068 gen_helper_fildl_FT0(cpu_env, s->tmp2_i32); 6069 break; 6070 case 2: 6071 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 6072 s->mem_index, MO_LEUQ); 6073 gen_helper_fldl_FT0(cpu_env, s->tmp1_i64); 6074 break; 6075 case 3: 6076 default: 6077 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 6078 s->mem_index, MO_LESW); 6079 gen_helper_fildl_FT0(cpu_env, s->tmp2_i32); 6080 break; 6081 } 6082 6083 gen_helper_fp_arith_ST0_FT0(op1); 6084 if (op1 == 3) { 6085 /* fcomp needs pop */ 6086 gen_helper_fpop(cpu_env); 6087 } 6088 } 6089 break; 6090 case 0x08: /* flds */ 6091 case 0x0a: /* fsts */ 6092 case 0x0b: /* fstps */ 6093 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 6094 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 6095 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 6096 switch (op & 7) { 6097 case 0: 6098 switch (op >> 4) { 6099 case 0: 6100 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 6101 s->mem_index, MO_LEUL); 6102 gen_helper_flds_ST0(cpu_env, s->tmp2_i32); 6103 break; 6104 case 1: 6105 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 6106 s->mem_index, MO_LEUL); 6107 gen_helper_fildl_ST0(cpu_env, s->tmp2_i32); 6108 break; 6109 case 2: 6110 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 6111 s->mem_index, MO_LEUQ); 6112 gen_helper_fldl_ST0(cpu_env, s->tmp1_i64); 6113 break; 6114 case 3: 6115 default: 6116 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 6117 s->mem_index, MO_LESW); 6118 gen_helper_fildl_ST0(cpu_env, s->tmp2_i32); 6119 break; 6120 } 6121 break; 6122 case 1: 6123 /* XXX: the corresponding CPUID bit must be tested ! */ 6124 switch (op >> 4) { 6125 case 1: 6126 gen_helper_fisttl_ST0(s->tmp2_i32, cpu_env); 6127 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 6128 s->mem_index, MO_LEUL); 6129 break; 6130 case 2: 6131 gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env); 6132 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 6133 s->mem_index, MO_LEUQ); 6134 break; 6135 case 3: 6136 default: 6137 gen_helper_fistt_ST0(s->tmp2_i32, cpu_env); 6138 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 6139 s->mem_index, MO_LEUW); 6140 break; 6141 } 6142 gen_helper_fpop(cpu_env); 6143 break; 6144 default: 6145 switch (op >> 4) { 6146 case 0: 6147 gen_helper_fsts_ST0(s->tmp2_i32, cpu_env); 6148 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 6149 s->mem_index, MO_LEUL); 6150 break; 6151 case 1: 6152 gen_helper_fistl_ST0(s->tmp2_i32, cpu_env); 6153 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 6154 s->mem_index, MO_LEUL); 6155 break; 6156 case 2: 6157 gen_helper_fstl_ST0(s->tmp1_i64, cpu_env); 6158 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 6159 s->mem_index, MO_LEUQ); 6160 break; 6161 case 3: 6162 default: 6163 gen_helper_fist_ST0(s->tmp2_i32, cpu_env); 6164 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 6165 s->mem_index, MO_LEUW); 6166 break; 6167 } 6168 if ((op & 7) == 3) { 6169 gen_helper_fpop(cpu_env); 6170 } 6171 break; 6172 } 6173 break; 6174 case 0x0c: /* fldenv mem */ 6175 gen_helper_fldenv(cpu_env, s->A0, 6176 tcg_const_i32(dflag - 1)); 6177 update_fip = update_fdp = false; 6178 break; 6179 case 0x0d: /* fldcw mem */ 6180 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 6181 s->mem_index, MO_LEUW); 6182 gen_helper_fldcw(cpu_env, s->tmp2_i32); 6183 update_fip = update_fdp = false; 6184 break; 6185 case 0x0e: /* fnstenv mem */ 6186 gen_helper_fstenv(cpu_env, s->A0, 6187 tcg_const_i32(dflag - 1)); 6188 update_fip = update_fdp = false; 6189 break; 6190 case 0x0f: /* fnstcw mem */ 6191 gen_helper_fnstcw(s->tmp2_i32, cpu_env); 6192 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 6193 s->mem_index, MO_LEUW); 6194 update_fip = update_fdp = false; 6195 break; 6196 case 0x1d: /* fldt mem */ 6197 gen_helper_fldt_ST0(cpu_env, s->A0); 6198 break; 6199 case 0x1f: /* fstpt mem */ 6200 gen_helper_fstt_ST0(cpu_env, s->A0); 6201 gen_helper_fpop(cpu_env); 6202 break; 6203 case 0x2c: /* frstor mem */ 6204 gen_helper_frstor(cpu_env, s->A0, 6205 tcg_const_i32(dflag - 1)); 6206 update_fip = update_fdp = false; 6207 break; 6208 case 0x2e: /* fnsave mem */ 6209 gen_helper_fsave(cpu_env, s->A0, 6210 tcg_const_i32(dflag - 1)); 6211 update_fip = update_fdp = false; 6212 break; 6213 case 0x2f: /* fnstsw mem */ 6214 gen_helper_fnstsw(s->tmp2_i32, cpu_env); 6215 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 6216 s->mem_index, MO_LEUW); 6217 update_fip = update_fdp = false; 6218 break; 6219 case 0x3c: /* fbld */ 6220 gen_helper_fbld_ST0(cpu_env, s->A0); 6221 break; 6222 case 0x3e: /* fbstp */ 6223 gen_helper_fbst_ST0(cpu_env, s->A0); 6224 gen_helper_fpop(cpu_env); 6225 break; 6226 case 0x3d: /* fildll */ 6227 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 6228 s->mem_index, MO_LEUQ); 6229 gen_helper_fildll_ST0(cpu_env, s->tmp1_i64); 6230 break; 6231 case 0x3f: /* fistpll */ 6232 gen_helper_fistll_ST0(s->tmp1_i64, cpu_env); 6233 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 6234 s->mem_index, MO_LEUQ); 6235 gen_helper_fpop(cpu_env); 6236 break; 6237 default: 6238 goto unknown_op; 6239 } 6240 6241 if (update_fdp) { 6242 int last_seg = s->override >= 0 ? s->override : a.def_seg; 6243 6244 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, 6245 offsetof(CPUX86State, 6246 segs[last_seg].selector)); 6247 tcg_gen_st16_i32(s->tmp2_i32, cpu_env, 6248 offsetof(CPUX86State, fpds)); 6249 tcg_gen_st_tl(last_addr, cpu_env, 6250 offsetof(CPUX86State, fpdp)); 6251 } 6252 tcg_temp_free(last_addr); 6253 } else { 6254 /* register float ops */ 6255 opreg = rm; 6256 6257 switch (op) { 6258 case 0x08: /* fld sti */ 6259 gen_helper_fpush(cpu_env); 6260 gen_helper_fmov_ST0_STN(cpu_env, 6261 tcg_const_i32((opreg + 1) & 7)); 6262 break; 6263 case 0x09: /* fxchg sti */ 6264 case 0x29: /* fxchg4 sti, undocumented op */ 6265 case 0x39: /* fxchg7 sti, undocumented op */ 6266 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg)); 6267 break; 6268 case 0x0a: /* grp d9/2 */ 6269 switch (rm) { 6270 case 0: /* fnop */ 6271 /* check exceptions (FreeBSD FPU probe) */ 6272 gen_helper_fwait(cpu_env); 6273 update_fip = false; 6274 break; 6275 default: 6276 goto unknown_op; 6277 } 6278 break; 6279 case 0x0c: /* grp d9/4 */ 6280 switch (rm) { 6281 case 0: /* fchs */ 6282 gen_helper_fchs_ST0(cpu_env); 6283 break; 6284 case 1: /* fabs */ 6285 gen_helper_fabs_ST0(cpu_env); 6286 break; 6287 case 4: /* ftst */ 6288 gen_helper_fldz_FT0(cpu_env); 6289 gen_helper_fcom_ST0_FT0(cpu_env); 6290 break; 6291 case 5: /* fxam */ 6292 gen_helper_fxam_ST0(cpu_env); 6293 break; 6294 default: 6295 goto unknown_op; 6296 } 6297 break; 6298 case 0x0d: /* grp d9/5 */ 6299 { 6300 switch (rm) { 6301 case 0: 6302 gen_helper_fpush(cpu_env); 6303 gen_helper_fld1_ST0(cpu_env); 6304 break; 6305 case 1: 6306 gen_helper_fpush(cpu_env); 6307 gen_helper_fldl2t_ST0(cpu_env); 6308 break; 6309 case 2: 6310 gen_helper_fpush(cpu_env); 6311 gen_helper_fldl2e_ST0(cpu_env); 6312 break; 6313 case 3: 6314 gen_helper_fpush(cpu_env); 6315 gen_helper_fldpi_ST0(cpu_env); 6316 break; 6317 case 4: 6318 gen_helper_fpush(cpu_env); 6319 gen_helper_fldlg2_ST0(cpu_env); 6320 break; 6321 case 5: 6322 gen_helper_fpush(cpu_env); 6323 gen_helper_fldln2_ST0(cpu_env); 6324 break; 6325 case 6: 6326 gen_helper_fpush(cpu_env); 6327 gen_helper_fldz_ST0(cpu_env); 6328 break; 6329 default: 6330 goto unknown_op; 6331 } 6332 } 6333 break; 6334 case 0x0e: /* grp d9/6 */ 6335 switch (rm) { 6336 case 0: /* f2xm1 */ 6337 gen_helper_f2xm1(cpu_env); 6338 break; 6339 case 1: /* fyl2x */ 6340 gen_helper_fyl2x(cpu_env); 6341 break; 6342 case 2: /* fptan */ 6343 gen_helper_fptan(cpu_env); 6344 break; 6345 case 3: /* fpatan */ 6346 gen_helper_fpatan(cpu_env); 6347 break; 6348 case 4: /* fxtract */ 6349 gen_helper_fxtract(cpu_env); 6350 break; 6351 case 5: /* fprem1 */ 6352 gen_helper_fprem1(cpu_env); 6353 break; 6354 case 6: /* fdecstp */ 6355 gen_helper_fdecstp(cpu_env); 6356 break; 6357 default: 6358 case 7: /* fincstp */ 6359 gen_helper_fincstp(cpu_env); 6360 break; 6361 } 6362 break; 6363 case 0x0f: /* grp d9/7 */ 6364 switch (rm) { 6365 case 0: /* fprem */ 6366 gen_helper_fprem(cpu_env); 6367 break; 6368 case 1: /* fyl2xp1 */ 6369 gen_helper_fyl2xp1(cpu_env); 6370 break; 6371 case 2: /* fsqrt */ 6372 gen_helper_fsqrt(cpu_env); 6373 break; 6374 case 3: /* fsincos */ 6375 gen_helper_fsincos(cpu_env); 6376 break; 6377 case 5: /* fscale */ 6378 gen_helper_fscale(cpu_env); 6379 break; 6380 case 4: /* frndint */ 6381 gen_helper_frndint(cpu_env); 6382 break; 6383 case 6: /* fsin */ 6384 gen_helper_fsin(cpu_env); 6385 break; 6386 default: 6387 case 7: /* fcos */ 6388 gen_helper_fcos(cpu_env); 6389 break; 6390 } 6391 break; 6392 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 6393 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 6394 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 6395 { 6396 int op1; 6397 6398 op1 = op & 7; 6399 if (op >= 0x20) { 6400 gen_helper_fp_arith_STN_ST0(op1, opreg); 6401 if (op >= 0x30) { 6402 gen_helper_fpop(cpu_env); 6403 } 6404 } else { 6405 gen_helper_fmov_FT0_STN(cpu_env, 6406 tcg_const_i32(opreg)); 6407 gen_helper_fp_arith_ST0_FT0(op1); 6408 } 6409 } 6410 break; 6411 case 0x02: /* fcom */ 6412 case 0x22: /* fcom2, undocumented op */ 6413 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6414 gen_helper_fcom_ST0_FT0(cpu_env); 6415 break; 6416 case 0x03: /* fcomp */ 6417 case 0x23: /* fcomp3, undocumented op */ 6418 case 0x32: /* fcomp5, undocumented op */ 6419 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6420 gen_helper_fcom_ST0_FT0(cpu_env); 6421 gen_helper_fpop(cpu_env); 6422 break; 6423 case 0x15: /* da/5 */ 6424 switch (rm) { 6425 case 1: /* fucompp */ 6426 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1)); 6427 gen_helper_fucom_ST0_FT0(cpu_env); 6428 gen_helper_fpop(cpu_env); 6429 gen_helper_fpop(cpu_env); 6430 break; 6431 default: 6432 goto unknown_op; 6433 } 6434 break; 6435 case 0x1c: 6436 switch (rm) { 6437 case 0: /* feni (287 only, just do nop here) */ 6438 break; 6439 case 1: /* fdisi (287 only, just do nop here) */ 6440 break; 6441 case 2: /* fclex */ 6442 gen_helper_fclex(cpu_env); 6443 update_fip = false; 6444 break; 6445 case 3: /* fninit */ 6446 gen_helper_fninit(cpu_env); 6447 update_fip = false; 6448 break; 6449 case 4: /* fsetpm (287 only, just do nop here) */ 6450 break; 6451 default: 6452 goto unknown_op; 6453 } 6454 break; 6455 case 0x1d: /* fucomi */ 6456 if (!(s->cpuid_features & CPUID_CMOV)) { 6457 goto illegal_op; 6458 } 6459 gen_update_cc_op(s); 6460 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6461 gen_helper_fucomi_ST0_FT0(cpu_env); 6462 set_cc_op(s, CC_OP_EFLAGS); 6463 break; 6464 case 0x1e: /* fcomi */ 6465 if (!(s->cpuid_features & CPUID_CMOV)) { 6466 goto illegal_op; 6467 } 6468 gen_update_cc_op(s); 6469 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6470 gen_helper_fcomi_ST0_FT0(cpu_env); 6471 set_cc_op(s, CC_OP_EFLAGS); 6472 break; 6473 case 0x28: /* ffree sti */ 6474 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg)); 6475 break; 6476 case 0x2a: /* fst sti */ 6477 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg)); 6478 break; 6479 case 0x2b: /* fstp sti */ 6480 case 0x0b: /* fstp1 sti, undocumented op */ 6481 case 0x3a: /* fstp8 sti, undocumented op */ 6482 case 0x3b: /* fstp9 sti, undocumented op */ 6483 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg)); 6484 gen_helper_fpop(cpu_env); 6485 break; 6486 case 0x2c: /* fucom st(i) */ 6487 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6488 gen_helper_fucom_ST0_FT0(cpu_env); 6489 break; 6490 case 0x2d: /* fucomp st(i) */ 6491 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6492 gen_helper_fucom_ST0_FT0(cpu_env); 6493 gen_helper_fpop(cpu_env); 6494 break; 6495 case 0x33: /* de/3 */ 6496 switch (rm) { 6497 case 1: /* fcompp */ 6498 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1)); 6499 gen_helper_fcom_ST0_FT0(cpu_env); 6500 gen_helper_fpop(cpu_env); 6501 gen_helper_fpop(cpu_env); 6502 break; 6503 default: 6504 goto unknown_op; 6505 } 6506 break; 6507 case 0x38: /* ffreep sti, undocumented op */ 6508 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg)); 6509 gen_helper_fpop(cpu_env); 6510 break; 6511 case 0x3c: /* df/4 */ 6512 switch (rm) { 6513 case 0: 6514 gen_helper_fnstsw(s->tmp2_i32, cpu_env); 6515 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 6516 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 6517 break; 6518 default: 6519 goto unknown_op; 6520 } 6521 break; 6522 case 0x3d: /* fucomip */ 6523 if (!(s->cpuid_features & CPUID_CMOV)) { 6524 goto illegal_op; 6525 } 6526 gen_update_cc_op(s); 6527 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6528 gen_helper_fucomi_ST0_FT0(cpu_env); 6529 gen_helper_fpop(cpu_env); 6530 set_cc_op(s, CC_OP_EFLAGS); 6531 break; 6532 case 0x3e: /* fcomip */ 6533 if (!(s->cpuid_features & CPUID_CMOV)) { 6534 goto illegal_op; 6535 } 6536 gen_update_cc_op(s); 6537 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6538 gen_helper_fcomi_ST0_FT0(cpu_env); 6539 gen_helper_fpop(cpu_env); 6540 set_cc_op(s, CC_OP_EFLAGS); 6541 break; 6542 case 0x10 ... 0x13: /* fcmovxx */ 6543 case 0x18 ... 0x1b: 6544 { 6545 int op1; 6546 TCGLabel *l1; 6547 static const uint8_t fcmov_cc[8] = { 6548 (JCC_B << 1), 6549 (JCC_Z << 1), 6550 (JCC_BE << 1), 6551 (JCC_P << 1), 6552 }; 6553 6554 if (!(s->cpuid_features & CPUID_CMOV)) { 6555 goto illegal_op; 6556 } 6557 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 6558 l1 = gen_new_label(); 6559 gen_jcc1_noeob(s, op1, l1); 6560 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg)); 6561 gen_set_label(l1); 6562 } 6563 break; 6564 default: 6565 goto unknown_op; 6566 } 6567 } 6568 6569 if (update_fip) { 6570 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, 6571 offsetof(CPUX86State, segs[R_CS].selector)); 6572 tcg_gen_st16_i32(s->tmp2_i32, cpu_env, 6573 offsetof(CPUX86State, fpcs)); 6574 tcg_gen_st_tl(eip_cur_tl(s), 6575 cpu_env, offsetof(CPUX86State, fpip)); 6576 } 6577 } 6578 break; 6579 /************************/ 6580 /* string ops */ 6581 6582 case 0xa4: /* movsS */ 6583 case 0xa5: 6584 ot = mo_b_d(b, dflag); 6585 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6586 gen_repz_movs(s, ot); 6587 } else { 6588 gen_movs(s, ot); 6589 } 6590 break; 6591 6592 case 0xaa: /* stosS */ 6593 case 0xab: 6594 ot = mo_b_d(b, dflag); 6595 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6596 gen_repz_stos(s, ot); 6597 } else { 6598 gen_stos(s, ot); 6599 } 6600 break; 6601 case 0xac: /* lodsS */ 6602 case 0xad: 6603 ot = mo_b_d(b, dflag); 6604 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6605 gen_repz_lods(s, ot); 6606 } else { 6607 gen_lods(s, ot); 6608 } 6609 break; 6610 case 0xae: /* scasS */ 6611 case 0xaf: 6612 ot = mo_b_d(b, dflag); 6613 if (prefixes & PREFIX_REPNZ) { 6614 gen_repz_scas(s, ot, 1); 6615 } else if (prefixes & PREFIX_REPZ) { 6616 gen_repz_scas(s, ot, 0); 6617 } else { 6618 gen_scas(s, ot); 6619 } 6620 break; 6621 6622 case 0xa6: /* cmpsS */ 6623 case 0xa7: 6624 ot = mo_b_d(b, dflag); 6625 if (prefixes & PREFIX_REPNZ) { 6626 gen_repz_cmps(s, ot, 1); 6627 } else if (prefixes & PREFIX_REPZ) { 6628 gen_repz_cmps(s, ot, 0); 6629 } else { 6630 gen_cmps(s, ot); 6631 } 6632 break; 6633 case 0x6c: /* insS */ 6634 case 0x6d: 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, 6639 SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) { 6640 break; 6641 } 6642 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6643 gen_io_start(); 6644 s->base.is_jmp = DISAS_TOO_MANY; 6645 } 6646 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6647 gen_repz_ins(s, ot); 6648 } else { 6649 gen_ins(s, ot); 6650 } 6651 break; 6652 case 0x6e: /* outsS */ 6653 case 0x6f: 6654 ot = mo_b_d32(b, dflag); 6655 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 6656 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 6657 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) { 6658 break; 6659 } 6660 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6661 gen_io_start(); 6662 s->base.is_jmp = DISAS_TOO_MANY; 6663 } 6664 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6665 gen_repz_outs(s, ot); 6666 } else { 6667 gen_outs(s, ot); 6668 } 6669 break; 6670 6671 /************************/ 6672 /* port I/O */ 6673 6674 case 0xe4: 6675 case 0xe5: 6676 ot = mo_b_d32(b, dflag); 6677 val = x86_ldub_code(env, s); 6678 tcg_gen_movi_i32(s->tmp2_i32, val); 6679 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) { 6680 break; 6681 } 6682 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6683 gen_io_start(); 6684 s->base.is_jmp = DISAS_TOO_MANY; 6685 } 6686 gen_helper_in_func(ot, s->T1, s->tmp2_i32); 6687 gen_op_mov_reg_v(s, ot, R_EAX, s->T1); 6688 gen_bpt_io(s, s->tmp2_i32, ot); 6689 break; 6690 case 0xe6: 6691 case 0xe7: 6692 ot = mo_b_d32(b, dflag); 6693 val = x86_ldub_code(env, s); 6694 tcg_gen_movi_i32(s->tmp2_i32, val); 6695 if (!gen_check_io(s, ot, s->tmp2_i32, 0)) { 6696 break; 6697 } 6698 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6699 gen_io_start(); 6700 s->base.is_jmp = DISAS_TOO_MANY; 6701 } 6702 gen_op_mov_v_reg(s, ot, s->T1, R_EAX); 6703 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 6704 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 6705 gen_bpt_io(s, s->tmp2_i32, ot); 6706 break; 6707 case 0xec: 6708 case 0xed: 6709 ot = mo_b_d32(b, dflag); 6710 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 6711 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 6712 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) { 6713 break; 6714 } 6715 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6716 gen_io_start(); 6717 s->base.is_jmp = DISAS_TOO_MANY; 6718 } 6719 gen_helper_in_func(ot, s->T1, s->tmp2_i32); 6720 gen_op_mov_reg_v(s, ot, R_EAX, s->T1); 6721 gen_bpt_io(s, s->tmp2_i32, ot); 6722 break; 6723 case 0xee: 6724 case 0xef: 6725 ot = mo_b_d32(b, dflag); 6726 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 6727 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 6728 if (!gen_check_io(s, ot, s->tmp2_i32, 0)) { 6729 break; 6730 } 6731 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6732 gen_io_start(); 6733 s->base.is_jmp = DISAS_TOO_MANY; 6734 } 6735 gen_op_mov_v_reg(s, ot, s->T1, R_EAX); 6736 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 6737 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 6738 gen_bpt_io(s, s->tmp2_i32, ot); 6739 break; 6740 6741 /************************/ 6742 /* control */ 6743 case 0xc2: /* ret im */ 6744 val = x86_ldsw_code(env, s); 6745 ot = gen_pop_T0(s); 6746 gen_stack_update(s, val + (1 << ot)); 6747 /* Note that gen_pop_T0 uses a zero-extending load. */ 6748 gen_op_jmp_v(s, s->T0); 6749 gen_bnd_jmp(s); 6750 s->base.is_jmp = DISAS_JUMP; 6751 break; 6752 case 0xc3: /* ret */ 6753 ot = gen_pop_T0(s); 6754 gen_pop_update(s, ot); 6755 /* Note that gen_pop_T0 uses a zero-extending load. */ 6756 gen_op_jmp_v(s, s->T0); 6757 gen_bnd_jmp(s); 6758 s->base.is_jmp = DISAS_JUMP; 6759 break; 6760 case 0xca: /* lret im */ 6761 val = x86_ldsw_code(env, s); 6762 do_lret: 6763 if (PE(s) && !VM86(s)) { 6764 gen_update_cc_op(s); 6765 gen_update_eip_cur(s); 6766 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1), 6767 tcg_const_i32(val)); 6768 } else { 6769 gen_stack_A0(s); 6770 /* pop offset */ 6771 gen_op_ld_v(s, dflag, s->T0, s->A0); 6772 /* NOTE: keeping EIP updated is not a problem in case of 6773 exception */ 6774 gen_op_jmp_v(s, s->T0); 6775 /* pop selector */ 6776 gen_add_A0_im(s, 1 << dflag); 6777 gen_op_ld_v(s, dflag, s->T0, s->A0); 6778 gen_op_movl_seg_T0_vm(s, R_CS); 6779 /* add stack offset */ 6780 gen_stack_update(s, val + (2 << dflag)); 6781 } 6782 s->base.is_jmp = DISAS_EOB_ONLY; 6783 break; 6784 case 0xcb: /* lret */ 6785 val = 0; 6786 goto do_lret; 6787 case 0xcf: /* iret */ 6788 gen_svm_check_intercept(s, SVM_EXIT_IRET); 6789 if (!PE(s) || VM86(s)) { 6790 /* real mode or vm86 mode */ 6791 if (!check_vm86_iopl(s)) { 6792 break; 6793 } 6794 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1)); 6795 } else { 6796 gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1), 6797 eip_next_i32(s)); 6798 } 6799 set_cc_op(s, CC_OP_EFLAGS); 6800 s->base.is_jmp = DISAS_EOB_ONLY; 6801 break; 6802 case 0xe8: /* call im */ 6803 { 6804 int diff = (dflag != MO_16 6805 ? (int32_t)insn_get(env, s, MO_32) 6806 : (int16_t)insn_get(env, s, MO_16)); 6807 gen_push_v(s, eip_next_tl(s)); 6808 gen_bnd_jmp(s); 6809 gen_jmp_rel(s, dflag, diff, 0); 6810 } 6811 break; 6812 case 0x9a: /* lcall im */ 6813 { 6814 unsigned int selector, offset; 6815 6816 if (CODE64(s)) 6817 goto illegal_op; 6818 ot = dflag; 6819 offset = insn_get(env, s, ot); 6820 selector = insn_get(env, s, MO_16); 6821 6822 tcg_gen_movi_tl(s->T0, selector); 6823 tcg_gen_movi_tl(s->T1, offset); 6824 } 6825 goto do_lcall; 6826 case 0xe9: /* jmp im */ 6827 { 6828 int diff = (dflag != MO_16 6829 ? (int32_t)insn_get(env, s, MO_32) 6830 : (int16_t)insn_get(env, s, MO_16)); 6831 gen_bnd_jmp(s); 6832 gen_jmp_rel(s, dflag, diff, 0); 6833 } 6834 break; 6835 case 0xea: /* ljmp im */ 6836 { 6837 unsigned int selector, offset; 6838 6839 if (CODE64(s)) 6840 goto illegal_op; 6841 ot = dflag; 6842 offset = insn_get(env, s, ot); 6843 selector = insn_get(env, s, MO_16); 6844 6845 tcg_gen_movi_tl(s->T0, selector); 6846 tcg_gen_movi_tl(s->T1, offset); 6847 } 6848 goto do_ljmp; 6849 case 0xeb: /* jmp Jb */ 6850 { 6851 int diff = (int8_t)insn_get(env, s, MO_8); 6852 gen_jmp_rel(s, dflag, diff, 0); 6853 } 6854 break; 6855 case 0x70 ... 0x7f: /* jcc Jb */ 6856 { 6857 int diff = (int8_t)insn_get(env, s, MO_8); 6858 gen_bnd_jmp(s); 6859 gen_jcc(s, b, diff); 6860 } 6861 break; 6862 case 0x180 ... 0x18f: /* jcc Jv */ 6863 { 6864 int diff = (dflag != MO_16 6865 ? (int32_t)insn_get(env, s, MO_32) 6866 : (int16_t)insn_get(env, s, MO_16)); 6867 gen_bnd_jmp(s); 6868 gen_jcc(s, b, diff); 6869 } 6870 break; 6871 6872 case 0x190 ... 0x19f: /* setcc Gv */ 6873 modrm = x86_ldub_code(env, s); 6874 gen_setcc1(s, b, s->T0); 6875 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1); 6876 break; 6877 case 0x140 ... 0x14f: /* cmov Gv, Ev */ 6878 if (!(s->cpuid_features & CPUID_CMOV)) { 6879 goto illegal_op; 6880 } 6881 ot = dflag; 6882 modrm = x86_ldub_code(env, s); 6883 reg = ((modrm >> 3) & 7) | REX_R(s); 6884 gen_cmovcc1(env, s, ot, b, modrm, reg); 6885 break; 6886 6887 /************************/ 6888 /* flags */ 6889 case 0x9c: /* pushf */ 6890 gen_svm_check_intercept(s, SVM_EXIT_PUSHF); 6891 if (check_vm86_iopl(s)) { 6892 gen_update_cc_op(s); 6893 gen_helper_read_eflags(s->T0, cpu_env); 6894 gen_push_v(s, s->T0); 6895 } 6896 break; 6897 case 0x9d: /* popf */ 6898 gen_svm_check_intercept(s, SVM_EXIT_POPF); 6899 if (check_vm86_iopl(s)) { 6900 ot = gen_pop_T0(s); 6901 if (CPL(s) == 0) { 6902 if (dflag != MO_16) { 6903 gen_helper_write_eflags(cpu_env, s->T0, 6904 tcg_const_i32((TF_MASK | AC_MASK | 6905 ID_MASK | NT_MASK | 6906 IF_MASK | 6907 IOPL_MASK))); 6908 } else { 6909 gen_helper_write_eflags(cpu_env, s->T0, 6910 tcg_const_i32((TF_MASK | AC_MASK | 6911 ID_MASK | NT_MASK | 6912 IF_MASK | IOPL_MASK) 6913 & 0xffff)); 6914 } 6915 } else { 6916 if (CPL(s) <= IOPL(s)) { 6917 if (dflag != MO_16) { 6918 gen_helper_write_eflags(cpu_env, s->T0, 6919 tcg_const_i32((TF_MASK | 6920 AC_MASK | 6921 ID_MASK | 6922 NT_MASK | 6923 IF_MASK))); 6924 } else { 6925 gen_helper_write_eflags(cpu_env, s->T0, 6926 tcg_const_i32((TF_MASK | 6927 AC_MASK | 6928 ID_MASK | 6929 NT_MASK | 6930 IF_MASK) 6931 & 0xffff)); 6932 } 6933 } else { 6934 if (dflag != MO_16) { 6935 gen_helper_write_eflags(cpu_env, s->T0, 6936 tcg_const_i32((TF_MASK | AC_MASK | 6937 ID_MASK | NT_MASK))); 6938 } else { 6939 gen_helper_write_eflags(cpu_env, s->T0, 6940 tcg_const_i32((TF_MASK | AC_MASK | 6941 ID_MASK | NT_MASK) 6942 & 0xffff)); 6943 } 6944 } 6945 } 6946 gen_pop_update(s, ot); 6947 set_cc_op(s, CC_OP_EFLAGS); 6948 /* abort translation because TF/AC flag may change */ 6949 s->base.is_jmp = DISAS_EOB_NEXT; 6950 } 6951 break; 6952 case 0x9e: /* sahf */ 6953 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) 6954 goto illegal_op; 6955 gen_op_mov_v_reg(s, MO_8, s->T0, R_AH); 6956 gen_compute_eflags(s); 6957 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O); 6958 tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C); 6959 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0); 6960 break; 6961 case 0x9f: /* lahf */ 6962 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) 6963 goto illegal_op; 6964 gen_compute_eflags(s); 6965 /* Note: gen_compute_eflags() only gives the condition codes */ 6966 tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02); 6967 gen_op_mov_reg_v(s, MO_8, R_AH, s->T0); 6968 break; 6969 case 0xf5: /* cmc */ 6970 gen_compute_eflags(s); 6971 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C); 6972 break; 6973 case 0xf8: /* clc */ 6974 gen_compute_eflags(s); 6975 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C); 6976 break; 6977 case 0xf9: /* stc */ 6978 gen_compute_eflags(s); 6979 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C); 6980 break; 6981 case 0xfc: /* cld */ 6982 tcg_gen_movi_i32(s->tmp2_i32, 1); 6983 tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df)); 6984 break; 6985 case 0xfd: /* std */ 6986 tcg_gen_movi_i32(s->tmp2_i32, -1); 6987 tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df)); 6988 break; 6989 6990 /************************/ 6991 /* bit operations */ 6992 case 0x1ba: /* bt/bts/btr/btc Gv, im */ 6993 ot = dflag; 6994 modrm = x86_ldub_code(env, s); 6995 op = (modrm >> 3) & 7; 6996 mod = (modrm >> 6) & 3; 6997 rm = (modrm & 7) | REX_B(s); 6998 if (mod != 3) { 6999 s->rip_offset = 1; 7000 gen_lea_modrm(env, s, modrm); 7001 if (!(s->prefix & PREFIX_LOCK)) { 7002 gen_op_ld_v(s, ot, s->T0, s->A0); 7003 } 7004 } else { 7005 gen_op_mov_v_reg(s, ot, s->T0, rm); 7006 } 7007 /* load shift */ 7008 val = x86_ldub_code(env, s); 7009 tcg_gen_movi_tl(s->T1, val); 7010 if (op < 4) 7011 goto unknown_op; 7012 op -= 4; 7013 goto bt_op; 7014 case 0x1a3: /* bt Gv, Ev */ 7015 op = 0; 7016 goto do_btx; 7017 case 0x1ab: /* bts */ 7018 op = 1; 7019 goto do_btx; 7020 case 0x1b3: /* btr */ 7021 op = 2; 7022 goto do_btx; 7023 case 0x1bb: /* btc */ 7024 op = 3; 7025 do_btx: 7026 ot = dflag; 7027 modrm = x86_ldub_code(env, s); 7028 reg = ((modrm >> 3) & 7) | REX_R(s); 7029 mod = (modrm >> 6) & 3; 7030 rm = (modrm & 7) | REX_B(s); 7031 gen_op_mov_v_reg(s, MO_32, s->T1, reg); 7032 if (mod != 3) { 7033 AddressParts a = gen_lea_modrm_0(env, s, modrm); 7034 /* specific case: we need to add a displacement */ 7035 gen_exts(ot, s->T1); 7036 tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot); 7037 tcg_gen_shli_tl(s->tmp0, s->tmp0, ot); 7038 tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0); 7039 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 7040 if (!(s->prefix & PREFIX_LOCK)) { 7041 gen_op_ld_v(s, ot, s->T0, s->A0); 7042 } 7043 } else { 7044 gen_op_mov_v_reg(s, ot, s->T0, rm); 7045 } 7046 bt_op: 7047 tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1); 7048 tcg_gen_movi_tl(s->tmp0, 1); 7049 tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1); 7050 if (s->prefix & PREFIX_LOCK) { 7051 switch (op) { 7052 case 0: /* bt */ 7053 /* Needs no atomic ops; we surpressed the normal 7054 memory load for LOCK above so do it now. */ 7055 gen_op_ld_v(s, ot, s->T0, s->A0); 7056 break; 7057 case 1: /* bts */ 7058 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0, 7059 s->mem_index, ot | MO_LE); 7060 break; 7061 case 2: /* btr */ 7062 tcg_gen_not_tl(s->tmp0, s->tmp0); 7063 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0, 7064 s->mem_index, ot | MO_LE); 7065 break; 7066 default: 7067 case 3: /* btc */ 7068 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0, 7069 s->mem_index, ot | MO_LE); 7070 break; 7071 } 7072 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 7073 } else { 7074 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 7075 switch (op) { 7076 case 0: /* bt */ 7077 /* Data already loaded; nothing to do. */ 7078 break; 7079 case 1: /* bts */ 7080 tcg_gen_or_tl(s->T0, s->T0, s->tmp0); 7081 break; 7082 case 2: /* btr */ 7083 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0); 7084 break; 7085 default: 7086 case 3: /* btc */ 7087 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0); 7088 break; 7089 } 7090 if (op != 0) { 7091 if (mod != 3) { 7092 gen_op_st_v(s, ot, s->T0, s->A0); 7093 } else { 7094 gen_op_mov_reg_v(s, ot, rm, s->T0); 7095 } 7096 } 7097 } 7098 7099 /* Delay all CC updates until after the store above. Note that 7100 C is the result of the test, Z is unchanged, and the others 7101 are all undefined. */ 7102 switch (s->cc_op) { 7103 case CC_OP_MULB ... CC_OP_MULQ: 7104 case CC_OP_ADDB ... CC_OP_ADDQ: 7105 case CC_OP_ADCB ... CC_OP_ADCQ: 7106 case CC_OP_SUBB ... CC_OP_SUBQ: 7107 case CC_OP_SBBB ... CC_OP_SBBQ: 7108 case CC_OP_LOGICB ... CC_OP_LOGICQ: 7109 case CC_OP_INCB ... CC_OP_INCQ: 7110 case CC_OP_DECB ... CC_OP_DECQ: 7111 case CC_OP_SHLB ... CC_OP_SHLQ: 7112 case CC_OP_SARB ... CC_OP_SARQ: 7113 case CC_OP_BMILGB ... CC_OP_BMILGQ: 7114 /* Z was going to be computed from the non-zero status of CC_DST. 7115 We can get that same Z value (and the new C value) by leaving 7116 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the 7117 same width. */ 7118 tcg_gen_mov_tl(cpu_cc_src, s->tmp4); 7119 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB); 7120 break; 7121 default: 7122 /* Otherwise, generate EFLAGS and replace the C bit. */ 7123 gen_compute_eflags(s); 7124 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4, 7125 ctz32(CC_C), 1); 7126 break; 7127 } 7128 break; 7129 case 0x1bc: /* bsf / tzcnt */ 7130 case 0x1bd: /* bsr / lzcnt */ 7131 ot = dflag; 7132 modrm = x86_ldub_code(env, s); 7133 reg = ((modrm >> 3) & 7) | REX_R(s); 7134 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 7135 gen_extu(ot, s->T0); 7136 7137 /* Note that lzcnt and tzcnt are in different extensions. */ 7138 if ((prefixes & PREFIX_REPZ) 7139 && (b & 1 7140 ? s->cpuid_ext3_features & CPUID_EXT3_ABM 7141 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) { 7142 int size = 8 << ot; 7143 /* For lzcnt/tzcnt, C bit is defined related to the input. */ 7144 tcg_gen_mov_tl(cpu_cc_src, s->T0); 7145 if (b & 1) { 7146 /* For lzcnt, reduce the target_ulong result by the 7147 number of zeros that we expect to find at the top. */ 7148 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS); 7149 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size); 7150 } else { 7151 /* For tzcnt, a zero input must return the operand size. */ 7152 tcg_gen_ctzi_tl(s->T0, s->T0, size); 7153 } 7154 /* For lzcnt/tzcnt, Z bit is defined related to the result. */ 7155 gen_op_update1_cc(s); 7156 set_cc_op(s, CC_OP_BMILGB + ot); 7157 } else { 7158 /* For bsr/bsf, only the Z bit is defined and it is related 7159 to the input and not the result. */ 7160 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 7161 set_cc_op(s, CC_OP_LOGICB + ot); 7162 7163 /* ??? The manual says that the output is undefined when the 7164 input is zero, but real hardware leaves it unchanged, and 7165 real programs appear to depend on that. Accomplish this 7166 by passing the output as the value to return upon zero. */ 7167 if (b & 1) { 7168 /* For bsr, return the bit index of the first 1 bit, 7169 not the count of leading zeros. */ 7170 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1); 7171 tcg_gen_clz_tl(s->T0, s->T0, s->T1); 7172 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1); 7173 } else { 7174 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]); 7175 } 7176 } 7177 gen_op_mov_reg_v(s, ot, reg, s->T0); 7178 break; 7179 /************************/ 7180 /* bcd */ 7181 case 0x27: /* daa */ 7182 if (CODE64(s)) 7183 goto illegal_op; 7184 gen_update_cc_op(s); 7185 gen_helper_daa(cpu_env); 7186 set_cc_op(s, CC_OP_EFLAGS); 7187 break; 7188 case 0x2f: /* das */ 7189 if (CODE64(s)) 7190 goto illegal_op; 7191 gen_update_cc_op(s); 7192 gen_helper_das(cpu_env); 7193 set_cc_op(s, CC_OP_EFLAGS); 7194 break; 7195 case 0x37: /* aaa */ 7196 if (CODE64(s)) 7197 goto illegal_op; 7198 gen_update_cc_op(s); 7199 gen_helper_aaa(cpu_env); 7200 set_cc_op(s, CC_OP_EFLAGS); 7201 break; 7202 case 0x3f: /* aas */ 7203 if (CODE64(s)) 7204 goto illegal_op; 7205 gen_update_cc_op(s); 7206 gen_helper_aas(cpu_env); 7207 set_cc_op(s, CC_OP_EFLAGS); 7208 break; 7209 case 0xd4: /* aam */ 7210 if (CODE64(s)) 7211 goto illegal_op; 7212 val = x86_ldub_code(env, s); 7213 if (val == 0) { 7214 gen_exception(s, EXCP00_DIVZ); 7215 } else { 7216 gen_helper_aam(cpu_env, tcg_const_i32(val)); 7217 set_cc_op(s, CC_OP_LOGICB); 7218 } 7219 break; 7220 case 0xd5: /* aad */ 7221 if (CODE64(s)) 7222 goto illegal_op; 7223 val = x86_ldub_code(env, s); 7224 gen_helper_aad(cpu_env, tcg_const_i32(val)); 7225 set_cc_op(s, CC_OP_LOGICB); 7226 break; 7227 /************************/ 7228 /* misc */ 7229 case 0x90: /* nop */ 7230 /* XXX: correct lock test for all insn */ 7231 if (prefixes & PREFIX_LOCK) { 7232 goto illegal_op; 7233 } 7234 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */ 7235 if (REX_B(s)) { 7236 goto do_xchg_reg_eax; 7237 } 7238 if (prefixes & PREFIX_REPZ) { 7239 gen_update_cc_op(s); 7240 gen_update_eip_cur(s); 7241 gen_helper_pause(cpu_env, cur_insn_len_i32(s)); 7242 s->base.is_jmp = DISAS_NORETURN; 7243 } 7244 break; 7245 case 0x9b: /* fwait */ 7246 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == 7247 (HF_MP_MASK | HF_TS_MASK)) { 7248 gen_exception(s, EXCP07_PREX); 7249 } else { 7250 gen_helper_fwait(cpu_env); 7251 } 7252 break; 7253 case 0xcc: /* int3 */ 7254 gen_interrupt(s, EXCP03_INT3); 7255 break; 7256 case 0xcd: /* int N */ 7257 val = x86_ldub_code(env, s); 7258 if (check_vm86_iopl(s)) { 7259 gen_interrupt(s, val); 7260 } 7261 break; 7262 case 0xce: /* into */ 7263 if (CODE64(s)) 7264 goto illegal_op; 7265 gen_update_cc_op(s); 7266 gen_update_eip_cur(s); 7267 gen_helper_into(cpu_env, cur_insn_len_i32(s)); 7268 break; 7269 #ifdef WANT_ICEBP 7270 case 0xf1: /* icebp (undocumented, exits to external debugger) */ 7271 gen_svm_check_intercept(s, SVM_EXIT_ICEBP); 7272 gen_debug(s); 7273 break; 7274 #endif 7275 case 0xfa: /* cli */ 7276 if (check_iopl(s)) { 7277 gen_helper_cli(cpu_env); 7278 } 7279 break; 7280 case 0xfb: /* sti */ 7281 if (check_iopl(s)) { 7282 gen_helper_sti(cpu_env); 7283 /* interruptions are enabled only the first insn after sti */ 7284 gen_update_eip_next(s); 7285 gen_eob_inhibit_irq(s, true); 7286 } 7287 break; 7288 case 0x62: /* bound */ 7289 if (CODE64(s)) 7290 goto illegal_op; 7291 ot = dflag; 7292 modrm = x86_ldub_code(env, s); 7293 reg = (modrm >> 3) & 7; 7294 mod = (modrm >> 6) & 3; 7295 if (mod == 3) 7296 goto illegal_op; 7297 gen_op_mov_v_reg(s, ot, s->T0, reg); 7298 gen_lea_modrm(env, s, modrm); 7299 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 7300 if (ot == MO_16) { 7301 gen_helper_boundw(cpu_env, s->A0, s->tmp2_i32); 7302 } else { 7303 gen_helper_boundl(cpu_env, s->A0, s->tmp2_i32); 7304 } 7305 break; 7306 case 0x1c8 ... 0x1cf: /* bswap reg */ 7307 reg = (b & 7) | REX_B(s); 7308 #ifdef TARGET_X86_64 7309 if (dflag == MO_64) { 7310 tcg_gen_bswap64_i64(cpu_regs[reg], cpu_regs[reg]); 7311 break; 7312 } 7313 #endif 7314 tcg_gen_bswap32_tl(cpu_regs[reg], cpu_regs[reg], TCG_BSWAP_OZ); 7315 break; 7316 case 0xd6: /* salc */ 7317 if (CODE64(s)) 7318 goto illegal_op; 7319 gen_compute_eflags_c(s, s->T0); 7320 tcg_gen_neg_tl(s->T0, s->T0); 7321 gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0); 7322 break; 7323 case 0xe0: /* loopnz */ 7324 case 0xe1: /* loopz */ 7325 case 0xe2: /* loop */ 7326 case 0xe3: /* jecxz */ 7327 { 7328 TCGLabel *l1, *l2; 7329 int diff = (int8_t)insn_get(env, s, MO_8); 7330 7331 l1 = gen_new_label(); 7332 l2 = gen_new_label(); 7333 gen_update_cc_op(s); 7334 b &= 3; 7335 switch(b) { 7336 case 0: /* loopnz */ 7337 case 1: /* loopz */ 7338 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 7339 gen_op_jz_ecx(s, l2); 7340 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1); 7341 break; 7342 case 2: /* loop */ 7343 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 7344 gen_op_jnz_ecx(s, l1); 7345 break; 7346 default: 7347 case 3: /* jcxz */ 7348 gen_op_jz_ecx(s, l1); 7349 break; 7350 } 7351 7352 gen_set_label(l2); 7353 gen_jmp_rel_csize(s, 0, 1); 7354 7355 gen_set_label(l1); 7356 gen_jmp_rel(s, dflag, diff, 0); 7357 } 7358 break; 7359 case 0x130: /* wrmsr */ 7360 case 0x132: /* rdmsr */ 7361 if (check_cpl0(s)) { 7362 gen_update_cc_op(s); 7363 gen_update_eip_cur(s); 7364 if (b & 2) { 7365 gen_helper_rdmsr(cpu_env); 7366 } else { 7367 gen_helper_wrmsr(cpu_env); 7368 s->base.is_jmp = DISAS_EOB_NEXT; 7369 } 7370 } 7371 break; 7372 case 0x131: /* rdtsc */ 7373 gen_update_cc_op(s); 7374 gen_update_eip_cur(s); 7375 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 7376 gen_io_start(); 7377 s->base.is_jmp = DISAS_TOO_MANY; 7378 } 7379 gen_helper_rdtsc(cpu_env); 7380 break; 7381 case 0x133: /* rdpmc */ 7382 gen_update_cc_op(s); 7383 gen_update_eip_cur(s); 7384 gen_helper_rdpmc(cpu_env); 7385 s->base.is_jmp = DISAS_NORETURN; 7386 break; 7387 case 0x134: /* sysenter */ 7388 /* For Intel SYSENTER is valid on 64-bit */ 7389 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) 7390 goto illegal_op; 7391 if (!PE(s)) { 7392 gen_exception_gpf(s); 7393 } else { 7394 gen_helper_sysenter(cpu_env); 7395 s->base.is_jmp = DISAS_EOB_ONLY; 7396 } 7397 break; 7398 case 0x135: /* sysexit */ 7399 /* For Intel SYSEXIT is valid on 64-bit */ 7400 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) 7401 goto illegal_op; 7402 if (!PE(s)) { 7403 gen_exception_gpf(s); 7404 } else { 7405 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1)); 7406 s->base.is_jmp = DISAS_EOB_ONLY; 7407 } 7408 break; 7409 #ifdef TARGET_X86_64 7410 case 0x105: /* syscall */ 7411 /* XXX: is it usable in real mode ? */ 7412 gen_update_cc_op(s); 7413 gen_update_eip_cur(s); 7414 gen_helper_syscall(cpu_env, cur_insn_len_i32(s)); 7415 /* TF handling for the syscall insn is different. The TF bit is checked 7416 after the syscall insn completes. This allows #DB to not be 7417 generated after one has entered CPL0 if TF is set in FMASK. */ 7418 gen_eob_worker(s, false, true); 7419 break; 7420 case 0x107: /* sysret */ 7421 if (!PE(s)) { 7422 gen_exception_gpf(s); 7423 } else { 7424 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1)); 7425 /* condition codes are modified only in long mode */ 7426 if (LMA(s)) { 7427 set_cc_op(s, CC_OP_EFLAGS); 7428 } 7429 /* TF handling for the sysret insn is different. The TF bit is 7430 checked after the sysret insn completes. This allows #DB to be 7431 generated "as if" the syscall insn in userspace has just 7432 completed. */ 7433 gen_eob_worker(s, false, true); 7434 } 7435 break; 7436 #endif 7437 case 0x1a2: /* cpuid */ 7438 gen_update_cc_op(s); 7439 gen_update_eip_cur(s); 7440 gen_helper_cpuid(cpu_env); 7441 break; 7442 case 0xf4: /* hlt */ 7443 if (check_cpl0(s)) { 7444 gen_update_cc_op(s); 7445 gen_update_eip_cur(s); 7446 gen_helper_hlt(cpu_env, cur_insn_len_i32(s)); 7447 s->base.is_jmp = DISAS_NORETURN; 7448 } 7449 break; 7450 case 0x100: 7451 modrm = x86_ldub_code(env, s); 7452 mod = (modrm >> 6) & 3; 7453 op = (modrm >> 3) & 7; 7454 switch(op) { 7455 case 0: /* sldt */ 7456 if (!PE(s) || VM86(s)) 7457 goto illegal_op; 7458 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 7459 break; 7460 } 7461 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ); 7462 tcg_gen_ld32u_tl(s->T0, cpu_env, 7463 offsetof(CPUX86State, ldt.selector)); 7464 ot = mod == 3 ? dflag : MO_16; 7465 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 7466 break; 7467 case 2: /* lldt */ 7468 if (!PE(s) || VM86(s)) 7469 goto illegal_op; 7470 if (check_cpl0(s)) { 7471 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE); 7472 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 7473 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 7474 gen_helper_lldt(cpu_env, s->tmp2_i32); 7475 } 7476 break; 7477 case 1: /* str */ 7478 if (!PE(s) || VM86(s)) 7479 goto illegal_op; 7480 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 7481 break; 7482 } 7483 gen_svm_check_intercept(s, SVM_EXIT_TR_READ); 7484 tcg_gen_ld32u_tl(s->T0, cpu_env, 7485 offsetof(CPUX86State, tr.selector)); 7486 ot = mod == 3 ? dflag : MO_16; 7487 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 7488 break; 7489 case 3: /* ltr */ 7490 if (!PE(s) || VM86(s)) 7491 goto illegal_op; 7492 if (check_cpl0(s)) { 7493 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE); 7494 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 7495 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 7496 gen_helper_ltr(cpu_env, s->tmp2_i32); 7497 } 7498 break; 7499 case 4: /* verr */ 7500 case 5: /* verw */ 7501 if (!PE(s) || VM86(s)) 7502 goto illegal_op; 7503 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 7504 gen_update_cc_op(s); 7505 if (op == 4) { 7506 gen_helper_verr(cpu_env, s->T0); 7507 } else { 7508 gen_helper_verw(cpu_env, s->T0); 7509 } 7510 set_cc_op(s, CC_OP_EFLAGS); 7511 break; 7512 default: 7513 goto unknown_op; 7514 } 7515 break; 7516 7517 case 0x101: 7518 modrm = x86_ldub_code(env, s); 7519 switch (modrm) { 7520 CASE_MODRM_MEM_OP(0): /* sgdt */ 7521 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 7522 break; 7523 } 7524 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ); 7525 gen_lea_modrm(env, s, modrm); 7526 tcg_gen_ld32u_tl(s->T0, 7527 cpu_env, offsetof(CPUX86State, gdt.limit)); 7528 gen_op_st_v(s, MO_16, s->T0, s->A0); 7529 gen_add_A0_im(s, 2); 7530 tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base)); 7531 if (dflag == MO_16) { 7532 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 7533 } 7534 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 7535 break; 7536 7537 case 0xc8: /* monitor */ 7538 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 7539 goto illegal_op; 7540 } 7541 gen_update_cc_op(s); 7542 gen_update_eip_cur(s); 7543 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 7544 gen_extu(s->aflag, s->A0); 7545 gen_add_A0_ds_seg(s); 7546 gen_helper_monitor(cpu_env, s->A0); 7547 break; 7548 7549 case 0xc9: /* mwait */ 7550 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 7551 goto illegal_op; 7552 } 7553 gen_update_cc_op(s); 7554 gen_update_eip_cur(s); 7555 gen_helper_mwait(cpu_env, cur_insn_len_i32(s)); 7556 s->base.is_jmp = DISAS_NORETURN; 7557 break; 7558 7559 case 0xca: /* clac */ 7560 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 7561 || CPL(s) != 0) { 7562 goto illegal_op; 7563 } 7564 gen_helper_clac(cpu_env); 7565 s->base.is_jmp = DISAS_EOB_NEXT; 7566 break; 7567 7568 case 0xcb: /* stac */ 7569 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 7570 || CPL(s) != 0) { 7571 goto illegal_op; 7572 } 7573 gen_helper_stac(cpu_env); 7574 s->base.is_jmp = DISAS_EOB_NEXT; 7575 break; 7576 7577 CASE_MODRM_MEM_OP(1): /* sidt */ 7578 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 7579 break; 7580 } 7581 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ); 7582 gen_lea_modrm(env, s, modrm); 7583 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit)); 7584 gen_op_st_v(s, MO_16, s->T0, s->A0); 7585 gen_add_A0_im(s, 2); 7586 tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base)); 7587 if (dflag == MO_16) { 7588 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 7589 } 7590 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 7591 break; 7592 7593 case 0xd0: /* xgetbv */ 7594 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 7595 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 7596 | PREFIX_REPZ | PREFIX_REPNZ))) { 7597 goto illegal_op; 7598 } 7599 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 7600 gen_helper_xgetbv(s->tmp1_i64, cpu_env, s->tmp2_i32); 7601 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 7602 break; 7603 7604 case 0xd1: /* xsetbv */ 7605 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 7606 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 7607 | PREFIX_REPZ | PREFIX_REPNZ))) { 7608 goto illegal_op; 7609 } 7610 if (!check_cpl0(s)) { 7611 break; 7612 } 7613 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 7614 cpu_regs[R_EDX]); 7615 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 7616 gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64); 7617 /* End TB because translation flags may change. */ 7618 s->base.is_jmp = DISAS_EOB_NEXT; 7619 break; 7620 7621 case 0xd8: /* VMRUN */ 7622 if (!SVME(s) || !PE(s)) { 7623 goto illegal_op; 7624 } 7625 if (!check_cpl0(s)) { 7626 break; 7627 } 7628 gen_update_cc_op(s); 7629 gen_update_eip_cur(s); 7630 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1), 7631 cur_insn_len_i32(s)); 7632 tcg_gen_exit_tb(NULL, 0); 7633 s->base.is_jmp = DISAS_NORETURN; 7634 break; 7635 7636 case 0xd9: /* VMMCALL */ 7637 if (!SVME(s)) { 7638 goto illegal_op; 7639 } 7640 gen_update_cc_op(s); 7641 gen_update_eip_cur(s); 7642 gen_helper_vmmcall(cpu_env); 7643 break; 7644 7645 case 0xda: /* VMLOAD */ 7646 if (!SVME(s) || !PE(s)) { 7647 goto illegal_op; 7648 } 7649 if (!check_cpl0(s)) { 7650 break; 7651 } 7652 gen_update_cc_op(s); 7653 gen_update_eip_cur(s); 7654 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1)); 7655 break; 7656 7657 case 0xdb: /* VMSAVE */ 7658 if (!SVME(s) || !PE(s)) { 7659 goto illegal_op; 7660 } 7661 if (!check_cpl0(s)) { 7662 break; 7663 } 7664 gen_update_cc_op(s); 7665 gen_update_eip_cur(s); 7666 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1)); 7667 break; 7668 7669 case 0xdc: /* STGI */ 7670 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 7671 || !PE(s)) { 7672 goto illegal_op; 7673 } 7674 if (!check_cpl0(s)) { 7675 break; 7676 } 7677 gen_update_cc_op(s); 7678 gen_helper_stgi(cpu_env); 7679 s->base.is_jmp = DISAS_EOB_NEXT; 7680 break; 7681 7682 case 0xdd: /* CLGI */ 7683 if (!SVME(s) || !PE(s)) { 7684 goto illegal_op; 7685 } 7686 if (!check_cpl0(s)) { 7687 break; 7688 } 7689 gen_update_cc_op(s); 7690 gen_update_eip_cur(s); 7691 gen_helper_clgi(cpu_env); 7692 break; 7693 7694 case 0xde: /* SKINIT */ 7695 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 7696 || !PE(s)) { 7697 goto illegal_op; 7698 } 7699 gen_svm_check_intercept(s, SVM_EXIT_SKINIT); 7700 /* If not intercepted, not implemented -- raise #UD. */ 7701 goto illegal_op; 7702 7703 case 0xdf: /* INVLPGA */ 7704 if (!SVME(s) || !PE(s)) { 7705 goto illegal_op; 7706 } 7707 if (!check_cpl0(s)) { 7708 break; 7709 } 7710 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA); 7711 if (s->aflag == MO_64) { 7712 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 7713 } else { 7714 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]); 7715 } 7716 gen_helper_flush_page(cpu_env, s->A0); 7717 s->base.is_jmp = DISAS_EOB_NEXT; 7718 break; 7719 7720 CASE_MODRM_MEM_OP(2): /* lgdt */ 7721 if (!check_cpl0(s)) { 7722 break; 7723 } 7724 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE); 7725 gen_lea_modrm(env, s, modrm); 7726 gen_op_ld_v(s, MO_16, s->T1, s->A0); 7727 gen_add_A0_im(s, 2); 7728 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 7729 if (dflag == MO_16) { 7730 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 7731 } 7732 tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base)); 7733 tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, gdt.limit)); 7734 break; 7735 7736 CASE_MODRM_MEM_OP(3): /* lidt */ 7737 if (!check_cpl0(s)) { 7738 break; 7739 } 7740 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE); 7741 gen_lea_modrm(env, s, modrm); 7742 gen_op_ld_v(s, MO_16, s->T1, s->A0); 7743 gen_add_A0_im(s, 2); 7744 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 7745 if (dflag == MO_16) { 7746 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 7747 } 7748 tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base)); 7749 tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, idt.limit)); 7750 break; 7751 7752 CASE_MODRM_OP(4): /* smsw */ 7753 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 7754 break; 7755 } 7756 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0); 7757 tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0])); 7758 /* 7759 * In 32-bit mode, the higher 16 bits of the destination 7760 * register are undefined. In practice CR0[31:0] is stored 7761 * just like in 64-bit mode. 7762 */ 7763 mod = (modrm >> 6) & 3; 7764 ot = (mod != 3 ? MO_16 : s->dflag); 7765 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 7766 break; 7767 case 0xee: /* rdpkru */ 7768 if (prefixes & PREFIX_LOCK) { 7769 goto illegal_op; 7770 } 7771 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 7772 gen_helper_rdpkru(s->tmp1_i64, cpu_env, s->tmp2_i32); 7773 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 7774 break; 7775 case 0xef: /* wrpkru */ 7776 if (prefixes & PREFIX_LOCK) { 7777 goto illegal_op; 7778 } 7779 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 7780 cpu_regs[R_EDX]); 7781 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 7782 gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64); 7783 break; 7784 7785 CASE_MODRM_OP(6): /* lmsw */ 7786 if (!check_cpl0(s)) { 7787 break; 7788 } 7789 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 7790 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 7791 /* 7792 * Only the 4 lower bits of CR0 are modified. 7793 * PE cannot be set to zero if already set to one. 7794 */ 7795 tcg_gen_ld_tl(s->T1, cpu_env, offsetof(CPUX86State, cr[0])); 7796 tcg_gen_andi_tl(s->T0, s->T0, 0xf); 7797 tcg_gen_andi_tl(s->T1, s->T1, ~0xe); 7798 tcg_gen_or_tl(s->T0, s->T0, s->T1); 7799 gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0); 7800 s->base.is_jmp = DISAS_EOB_NEXT; 7801 break; 7802 7803 CASE_MODRM_MEM_OP(7): /* invlpg */ 7804 if (!check_cpl0(s)) { 7805 break; 7806 } 7807 gen_svm_check_intercept(s, SVM_EXIT_INVLPG); 7808 gen_lea_modrm(env, s, modrm); 7809 gen_helper_flush_page(cpu_env, s->A0); 7810 s->base.is_jmp = DISAS_EOB_NEXT; 7811 break; 7812 7813 case 0xf8: /* swapgs */ 7814 #ifdef TARGET_X86_64 7815 if (CODE64(s)) { 7816 if (check_cpl0(s)) { 7817 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]); 7818 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env, 7819 offsetof(CPUX86State, kernelgsbase)); 7820 tcg_gen_st_tl(s->T0, cpu_env, 7821 offsetof(CPUX86State, kernelgsbase)); 7822 } 7823 break; 7824 } 7825 #endif 7826 goto illegal_op; 7827 7828 case 0xf9: /* rdtscp */ 7829 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) { 7830 goto illegal_op; 7831 } 7832 gen_update_cc_op(s); 7833 gen_update_eip_cur(s); 7834 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 7835 gen_io_start(); 7836 s->base.is_jmp = DISAS_TOO_MANY; 7837 } 7838 gen_helper_rdtscp(cpu_env); 7839 break; 7840 7841 default: 7842 goto unknown_op; 7843 } 7844 break; 7845 7846 case 0x108: /* invd */ 7847 case 0x109: /* wbinvd */ 7848 if (check_cpl0(s)) { 7849 gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD); 7850 /* nothing to do */ 7851 } 7852 break; 7853 case 0x63: /* arpl or movslS (x86_64) */ 7854 #ifdef TARGET_X86_64 7855 if (CODE64(s)) { 7856 int d_ot; 7857 /* d_ot is the size of destination */ 7858 d_ot = dflag; 7859 7860 modrm = x86_ldub_code(env, s); 7861 reg = ((modrm >> 3) & 7) | REX_R(s); 7862 mod = (modrm >> 6) & 3; 7863 rm = (modrm & 7) | REX_B(s); 7864 7865 if (mod == 3) { 7866 gen_op_mov_v_reg(s, MO_32, s->T0, rm); 7867 /* sign extend */ 7868 if (d_ot == MO_64) { 7869 tcg_gen_ext32s_tl(s->T0, s->T0); 7870 } 7871 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 7872 } else { 7873 gen_lea_modrm(env, s, modrm); 7874 gen_op_ld_v(s, MO_32 | MO_SIGN, s->T0, s->A0); 7875 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 7876 } 7877 } else 7878 #endif 7879 { 7880 TCGLabel *label1; 7881 TCGv t0, t1, t2, a0; 7882 7883 if (!PE(s) || VM86(s)) 7884 goto illegal_op; 7885 t0 = tcg_temp_local_new(); 7886 t1 = tcg_temp_local_new(); 7887 t2 = tcg_temp_local_new(); 7888 ot = MO_16; 7889 modrm = x86_ldub_code(env, s); 7890 reg = (modrm >> 3) & 7; 7891 mod = (modrm >> 6) & 3; 7892 rm = modrm & 7; 7893 if (mod != 3) { 7894 gen_lea_modrm(env, s, modrm); 7895 gen_op_ld_v(s, ot, t0, s->A0); 7896 a0 = tcg_temp_local_new(); 7897 tcg_gen_mov_tl(a0, s->A0); 7898 } else { 7899 gen_op_mov_v_reg(s, ot, t0, rm); 7900 a0 = NULL; 7901 } 7902 gen_op_mov_v_reg(s, ot, t1, reg); 7903 tcg_gen_andi_tl(s->tmp0, t0, 3); 7904 tcg_gen_andi_tl(t1, t1, 3); 7905 tcg_gen_movi_tl(t2, 0); 7906 label1 = gen_new_label(); 7907 tcg_gen_brcond_tl(TCG_COND_GE, s->tmp0, t1, label1); 7908 tcg_gen_andi_tl(t0, t0, ~3); 7909 tcg_gen_or_tl(t0, t0, t1); 7910 tcg_gen_movi_tl(t2, CC_Z); 7911 gen_set_label(label1); 7912 if (mod != 3) { 7913 gen_op_st_v(s, ot, t0, a0); 7914 tcg_temp_free(a0); 7915 } else { 7916 gen_op_mov_reg_v(s, ot, rm, t0); 7917 } 7918 gen_compute_eflags(s); 7919 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z); 7920 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2); 7921 tcg_temp_free(t0); 7922 tcg_temp_free(t1); 7923 tcg_temp_free(t2); 7924 } 7925 break; 7926 case 0x102: /* lar */ 7927 case 0x103: /* lsl */ 7928 { 7929 TCGLabel *label1; 7930 TCGv t0; 7931 if (!PE(s) || VM86(s)) 7932 goto illegal_op; 7933 ot = dflag != MO_16 ? MO_32 : MO_16; 7934 modrm = x86_ldub_code(env, s); 7935 reg = ((modrm >> 3) & 7) | REX_R(s); 7936 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 7937 t0 = tcg_temp_local_new(); 7938 gen_update_cc_op(s); 7939 if (b == 0x102) { 7940 gen_helper_lar(t0, cpu_env, s->T0); 7941 } else { 7942 gen_helper_lsl(t0, cpu_env, s->T0); 7943 } 7944 tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z); 7945 label1 = gen_new_label(); 7946 tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1); 7947 gen_op_mov_reg_v(s, ot, reg, t0); 7948 gen_set_label(label1); 7949 set_cc_op(s, CC_OP_EFLAGS); 7950 tcg_temp_free(t0); 7951 } 7952 break; 7953 case 0x118: 7954 modrm = x86_ldub_code(env, s); 7955 mod = (modrm >> 6) & 3; 7956 op = (modrm >> 3) & 7; 7957 switch(op) { 7958 case 0: /* prefetchnta */ 7959 case 1: /* prefetchnt0 */ 7960 case 2: /* prefetchnt0 */ 7961 case 3: /* prefetchnt0 */ 7962 if (mod == 3) 7963 goto illegal_op; 7964 gen_nop_modrm(env, s, modrm); 7965 /* nothing more to do */ 7966 break; 7967 default: /* nop (multi byte) */ 7968 gen_nop_modrm(env, s, modrm); 7969 break; 7970 } 7971 break; 7972 case 0x11a: 7973 modrm = x86_ldub_code(env, s); 7974 if (s->flags & HF_MPX_EN_MASK) { 7975 mod = (modrm >> 6) & 3; 7976 reg = ((modrm >> 3) & 7) | REX_R(s); 7977 if (prefixes & PREFIX_REPZ) { 7978 /* bndcl */ 7979 if (reg >= 4 7980 || (prefixes & PREFIX_LOCK) 7981 || s->aflag == MO_16) { 7982 goto illegal_op; 7983 } 7984 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]); 7985 } else if (prefixes & PREFIX_REPNZ) { 7986 /* bndcu */ 7987 if (reg >= 4 7988 || (prefixes & PREFIX_LOCK) 7989 || s->aflag == MO_16) { 7990 goto illegal_op; 7991 } 7992 TCGv_i64 notu = tcg_temp_new_i64(); 7993 tcg_gen_not_i64(notu, cpu_bndu[reg]); 7994 gen_bndck(env, s, modrm, TCG_COND_GTU, notu); 7995 tcg_temp_free_i64(notu); 7996 } else if (prefixes & PREFIX_DATA) { 7997 /* bndmov -- from reg/mem */ 7998 if (reg >= 4 || s->aflag == MO_16) { 7999 goto illegal_op; 8000 } 8001 if (mod == 3) { 8002 int reg2 = (modrm & 7) | REX_B(s); 8003 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 8004 goto illegal_op; 8005 } 8006 if (s->flags & HF_MPX_IU_MASK) { 8007 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]); 8008 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]); 8009 } 8010 } else { 8011 gen_lea_modrm(env, s, modrm); 8012 if (CODE64(s)) { 8013 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 8014 s->mem_index, MO_LEUQ); 8015 tcg_gen_addi_tl(s->A0, s->A0, 8); 8016 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 8017 s->mem_index, MO_LEUQ); 8018 } else { 8019 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 8020 s->mem_index, MO_LEUL); 8021 tcg_gen_addi_tl(s->A0, s->A0, 4); 8022 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 8023 s->mem_index, MO_LEUL); 8024 } 8025 /* bnd registers are now in-use */ 8026 gen_set_hflag(s, HF_MPX_IU_MASK); 8027 } 8028 } else if (mod != 3) { 8029 /* bndldx */ 8030 AddressParts a = gen_lea_modrm_0(env, s, modrm); 8031 if (reg >= 4 8032 || (prefixes & PREFIX_LOCK) 8033 || s->aflag == MO_16 8034 || a.base < -1) { 8035 goto illegal_op; 8036 } 8037 if (a.base >= 0) { 8038 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 8039 } else { 8040 tcg_gen_movi_tl(s->A0, 0); 8041 } 8042 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 8043 if (a.index >= 0) { 8044 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 8045 } else { 8046 tcg_gen_movi_tl(s->T0, 0); 8047 } 8048 if (CODE64(s)) { 8049 gen_helper_bndldx64(cpu_bndl[reg], cpu_env, s->A0, s->T0); 8050 tcg_gen_ld_i64(cpu_bndu[reg], cpu_env, 8051 offsetof(CPUX86State, mmx_t0.MMX_Q(0))); 8052 } else { 8053 gen_helper_bndldx32(cpu_bndu[reg], cpu_env, s->A0, s->T0); 8054 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]); 8055 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32); 8056 } 8057 gen_set_hflag(s, HF_MPX_IU_MASK); 8058 } 8059 } 8060 gen_nop_modrm(env, s, modrm); 8061 break; 8062 case 0x11b: 8063 modrm = x86_ldub_code(env, s); 8064 if (s->flags & HF_MPX_EN_MASK) { 8065 mod = (modrm >> 6) & 3; 8066 reg = ((modrm >> 3) & 7) | REX_R(s); 8067 if (mod != 3 && (prefixes & PREFIX_REPZ)) { 8068 /* bndmk */ 8069 if (reg >= 4 8070 || (prefixes & PREFIX_LOCK) 8071 || s->aflag == MO_16) { 8072 goto illegal_op; 8073 } 8074 AddressParts a = gen_lea_modrm_0(env, s, modrm); 8075 if (a.base >= 0) { 8076 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]); 8077 if (!CODE64(s)) { 8078 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]); 8079 } 8080 } else if (a.base == -1) { 8081 /* no base register has lower bound of 0 */ 8082 tcg_gen_movi_i64(cpu_bndl[reg], 0); 8083 } else { 8084 /* rip-relative generates #ud */ 8085 goto illegal_op; 8086 } 8087 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false)); 8088 if (!CODE64(s)) { 8089 tcg_gen_ext32u_tl(s->A0, s->A0); 8090 } 8091 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0); 8092 /* bnd registers are now in-use */ 8093 gen_set_hflag(s, HF_MPX_IU_MASK); 8094 break; 8095 } else if (prefixes & PREFIX_REPNZ) { 8096 /* bndcn */ 8097 if (reg >= 4 8098 || (prefixes & PREFIX_LOCK) 8099 || s->aflag == MO_16) { 8100 goto illegal_op; 8101 } 8102 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]); 8103 } else if (prefixes & PREFIX_DATA) { 8104 /* bndmov -- to reg/mem */ 8105 if (reg >= 4 || s->aflag == MO_16) { 8106 goto illegal_op; 8107 } 8108 if (mod == 3) { 8109 int reg2 = (modrm & 7) | REX_B(s); 8110 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 8111 goto illegal_op; 8112 } 8113 if (s->flags & HF_MPX_IU_MASK) { 8114 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]); 8115 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]); 8116 } 8117 } else { 8118 gen_lea_modrm(env, s, modrm); 8119 if (CODE64(s)) { 8120 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 8121 s->mem_index, MO_LEUQ); 8122 tcg_gen_addi_tl(s->A0, s->A0, 8); 8123 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 8124 s->mem_index, MO_LEUQ); 8125 } else { 8126 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 8127 s->mem_index, MO_LEUL); 8128 tcg_gen_addi_tl(s->A0, s->A0, 4); 8129 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 8130 s->mem_index, MO_LEUL); 8131 } 8132 } 8133 } else if (mod != 3) { 8134 /* bndstx */ 8135 AddressParts a = gen_lea_modrm_0(env, s, modrm); 8136 if (reg >= 4 8137 || (prefixes & PREFIX_LOCK) 8138 || s->aflag == MO_16 8139 || a.base < -1) { 8140 goto illegal_op; 8141 } 8142 if (a.base >= 0) { 8143 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 8144 } else { 8145 tcg_gen_movi_tl(s->A0, 0); 8146 } 8147 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 8148 if (a.index >= 0) { 8149 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 8150 } else { 8151 tcg_gen_movi_tl(s->T0, 0); 8152 } 8153 if (CODE64(s)) { 8154 gen_helper_bndstx64(cpu_env, s->A0, s->T0, 8155 cpu_bndl[reg], cpu_bndu[reg]); 8156 } else { 8157 gen_helper_bndstx32(cpu_env, s->A0, s->T0, 8158 cpu_bndl[reg], cpu_bndu[reg]); 8159 } 8160 } 8161 } 8162 gen_nop_modrm(env, s, modrm); 8163 break; 8164 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */ 8165 modrm = x86_ldub_code(env, s); 8166 gen_nop_modrm(env, s, modrm); 8167 break; 8168 8169 case 0x120: /* mov reg, crN */ 8170 case 0x122: /* mov crN, reg */ 8171 if (!check_cpl0(s)) { 8172 break; 8173 } 8174 modrm = x86_ldub_code(env, s); 8175 /* 8176 * Ignore the mod bits (assume (modrm&0xc0)==0xc0). 8177 * AMD documentation (24594.pdf) and testing of Intel 386 and 486 8178 * processors all show that the mod bits are assumed to be 1's, 8179 * regardless of actual values. 8180 */ 8181 rm = (modrm & 7) | REX_B(s); 8182 reg = ((modrm >> 3) & 7) | REX_R(s); 8183 switch (reg) { 8184 case 0: 8185 if ((prefixes & PREFIX_LOCK) && 8186 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) { 8187 reg = 8; 8188 } 8189 break; 8190 case 2: 8191 case 3: 8192 case 4: 8193 case 8: 8194 break; 8195 default: 8196 goto unknown_op; 8197 } 8198 ot = (CODE64(s) ? MO_64 : MO_32); 8199 8200 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 8201 gen_io_start(); 8202 s->base.is_jmp = DISAS_TOO_MANY; 8203 } 8204 if (b & 2) { 8205 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg); 8206 gen_op_mov_v_reg(s, ot, s->T0, rm); 8207 gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0); 8208 s->base.is_jmp = DISAS_EOB_NEXT; 8209 } else { 8210 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg); 8211 gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg)); 8212 gen_op_mov_reg_v(s, ot, rm, s->T0); 8213 } 8214 break; 8215 8216 case 0x121: /* mov reg, drN */ 8217 case 0x123: /* mov drN, reg */ 8218 if (check_cpl0(s)) { 8219 modrm = x86_ldub_code(env, s); 8220 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). 8221 * AMD documentation (24594.pdf) and testing of 8222 * intel 386 and 486 processors all show that the mod bits 8223 * are assumed to be 1's, regardless of actual values. 8224 */ 8225 rm = (modrm & 7) | REX_B(s); 8226 reg = ((modrm >> 3) & 7) | REX_R(s); 8227 if (CODE64(s)) 8228 ot = MO_64; 8229 else 8230 ot = MO_32; 8231 if (reg >= 8) { 8232 goto illegal_op; 8233 } 8234 if (b & 2) { 8235 gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg); 8236 gen_op_mov_v_reg(s, ot, s->T0, rm); 8237 tcg_gen_movi_i32(s->tmp2_i32, reg); 8238 gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0); 8239 s->base.is_jmp = DISAS_EOB_NEXT; 8240 } else { 8241 gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg); 8242 tcg_gen_movi_i32(s->tmp2_i32, reg); 8243 gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32); 8244 gen_op_mov_reg_v(s, ot, rm, s->T0); 8245 } 8246 } 8247 break; 8248 case 0x106: /* clts */ 8249 if (check_cpl0(s)) { 8250 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 8251 gen_helper_clts(cpu_env); 8252 /* abort block because static cpu state changed */ 8253 s->base.is_jmp = DISAS_EOB_NEXT; 8254 } 8255 break; 8256 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */ 8257 case 0x1c3: /* MOVNTI reg, mem */ 8258 if (!(s->cpuid_features & CPUID_SSE2)) 8259 goto illegal_op; 8260 ot = mo_64_32(dflag); 8261 modrm = x86_ldub_code(env, s); 8262 mod = (modrm >> 6) & 3; 8263 if (mod == 3) 8264 goto illegal_op; 8265 reg = ((modrm >> 3) & 7) | REX_R(s); 8266 /* generate a generic store */ 8267 gen_ldst_modrm(env, s, modrm, ot, reg, 1); 8268 break; 8269 case 0x1ae: 8270 modrm = x86_ldub_code(env, s); 8271 switch (modrm) { 8272 CASE_MODRM_MEM_OP(0): /* fxsave */ 8273 if (!(s->cpuid_features & CPUID_FXSR) 8274 || (prefixes & PREFIX_LOCK)) { 8275 goto illegal_op; 8276 } 8277 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 8278 gen_exception(s, EXCP07_PREX); 8279 break; 8280 } 8281 gen_lea_modrm(env, s, modrm); 8282 gen_helper_fxsave(cpu_env, s->A0); 8283 break; 8284 8285 CASE_MODRM_MEM_OP(1): /* fxrstor */ 8286 if (!(s->cpuid_features & CPUID_FXSR) 8287 || (prefixes & PREFIX_LOCK)) { 8288 goto illegal_op; 8289 } 8290 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 8291 gen_exception(s, EXCP07_PREX); 8292 break; 8293 } 8294 gen_lea_modrm(env, s, modrm); 8295 gen_helper_fxrstor(cpu_env, s->A0); 8296 break; 8297 8298 CASE_MODRM_MEM_OP(2): /* ldmxcsr */ 8299 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 8300 goto illegal_op; 8301 } 8302 if (s->flags & HF_TS_MASK) { 8303 gen_exception(s, EXCP07_PREX); 8304 break; 8305 } 8306 gen_lea_modrm(env, s, modrm); 8307 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL); 8308 gen_helper_ldmxcsr(cpu_env, s->tmp2_i32); 8309 break; 8310 8311 CASE_MODRM_MEM_OP(3): /* stmxcsr */ 8312 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 8313 goto illegal_op; 8314 } 8315 if (s->flags & HF_TS_MASK) { 8316 gen_exception(s, EXCP07_PREX); 8317 break; 8318 } 8319 gen_helper_update_mxcsr(cpu_env); 8320 gen_lea_modrm(env, s, modrm); 8321 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, mxcsr)); 8322 gen_op_st_v(s, MO_32, s->T0, s->A0); 8323 break; 8324 8325 CASE_MODRM_MEM_OP(4): /* xsave */ 8326 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 8327 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 8328 | PREFIX_REPZ | PREFIX_REPNZ))) { 8329 goto illegal_op; 8330 } 8331 gen_lea_modrm(env, s, modrm); 8332 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 8333 cpu_regs[R_EDX]); 8334 gen_helper_xsave(cpu_env, s->A0, s->tmp1_i64); 8335 break; 8336 8337 CASE_MODRM_MEM_OP(5): /* xrstor */ 8338 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 8339 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 8340 | PREFIX_REPZ | PREFIX_REPNZ))) { 8341 goto illegal_op; 8342 } 8343 gen_lea_modrm(env, s, modrm); 8344 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 8345 cpu_regs[R_EDX]); 8346 gen_helper_xrstor(cpu_env, s->A0, s->tmp1_i64); 8347 /* XRSTOR is how MPX is enabled, which changes how 8348 we translate. Thus we need to end the TB. */ 8349 s->base.is_jmp = DISAS_EOB_NEXT; 8350 break; 8351 8352 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */ 8353 if (prefixes & PREFIX_LOCK) { 8354 goto illegal_op; 8355 } 8356 if (prefixes & PREFIX_DATA) { 8357 /* clwb */ 8358 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) { 8359 goto illegal_op; 8360 } 8361 gen_nop_modrm(env, s, modrm); 8362 } else { 8363 /* xsaveopt */ 8364 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 8365 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0 8366 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) { 8367 goto illegal_op; 8368 } 8369 gen_lea_modrm(env, s, modrm); 8370 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 8371 cpu_regs[R_EDX]); 8372 gen_helper_xsaveopt(cpu_env, s->A0, s->tmp1_i64); 8373 } 8374 break; 8375 8376 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */ 8377 if (prefixes & PREFIX_LOCK) { 8378 goto illegal_op; 8379 } 8380 if (prefixes & PREFIX_DATA) { 8381 /* clflushopt */ 8382 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) { 8383 goto illegal_op; 8384 } 8385 } else { 8386 /* clflush */ 8387 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) 8388 || !(s->cpuid_features & CPUID_CLFLUSH)) { 8389 goto illegal_op; 8390 } 8391 } 8392 gen_nop_modrm(env, s, modrm); 8393 break; 8394 8395 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */ 8396 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */ 8397 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */ 8398 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */ 8399 if (CODE64(s) 8400 && (prefixes & PREFIX_REPZ) 8401 && !(prefixes & PREFIX_LOCK) 8402 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) { 8403 TCGv base, treg, src, dst; 8404 8405 /* Preserve hflags bits by testing CR4 at runtime. */ 8406 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK); 8407 gen_helper_cr4_testbit(cpu_env, s->tmp2_i32); 8408 8409 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS]; 8410 treg = cpu_regs[(modrm & 7) | REX_B(s)]; 8411 8412 if (modrm & 0x10) { 8413 /* wr*base */ 8414 dst = base, src = treg; 8415 } else { 8416 /* rd*base */ 8417 dst = treg, src = base; 8418 } 8419 8420 if (s->dflag == MO_32) { 8421 tcg_gen_ext32u_tl(dst, src); 8422 } else { 8423 tcg_gen_mov_tl(dst, src); 8424 } 8425 break; 8426 } 8427 goto unknown_op; 8428 8429 case 0xf8: /* sfence / pcommit */ 8430 if (prefixes & PREFIX_DATA) { 8431 /* pcommit */ 8432 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT) 8433 || (prefixes & PREFIX_LOCK)) { 8434 goto illegal_op; 8435 } 8436 break; 8437 } 8438 /* fallthru */ 8439 case 0xf9 ... 0xff: /* sfence */ 8440 if (!(s->cpuid_features & CPUID_SSE) 8441 || (prefixes & PREFIX_LOCK)) { 8442 goto illegal_op; 8443 } 8444 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC); 8445 break; 8446 case 0xe8 ... 0xef: /* lfence */ 8447 if (!(s->cpuid_features & CPUID_SSE) 8448 || (prefixes & PREFIX_LOCK)) { 8449 goto illegal_op; 8450 } 8451 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC); 8452 break; 8453 case 0xf0 ... 0xf7: /* mfence */ 8454 if (!(s->cpuid_features & CPUID_SSE2) 8455 || (prefixes & PREFIX_LOCK)) { 8456 goto illegal_op; 8457 } 8458 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 8459 break; 8460 8461 default: 8462 goto unknown_op; 8463 } 8464 break; 8465 8466 case 0x10d: /* 3DNow! prefetch(w) */ 8467 modrm = x86_ldub_code(env, s); 8468 mod = (modrm >> 6) & 3; 8469 if (mod == 3) 8470 goto illegal_op; 8471 gen_nop_modrm(env, s, modrm); 8472 break; 8473 case 0x1aa: /* rsm */ 8474 gen_svm_check_intercept(s, SVM_EXIT_RSM); 8475 if (!(s->flags & HF_SMM_MASK)) 8476 goto illegal_op; 8477 #ifdef CONFIG_USER_ONLY 8478 /* we should not be in SMM mode */ 8479 g_assert_not_reached(); 8480 #else 8481 gen_update_cc_op(s); 8482 gen_update_eip_next(s); 8483 gen_helper_rsm(cpu_env); 8484 #endif /* CONFIG_USER_ONLY */ 8485 s->base.is_jmp = DISAS_EOB_ONLY; 8486 break; 8487 case 0x1b8: /* SSE4.2 popcnt */ 8488 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) != 8489 PREFIX_REPZ) 8490 goto illegal_op; 8491 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT)) 8492 goto illegal_op; 8493 8494 modrm = x86_ldub_code(env, s); 8495 reg = ((modrm >> 3) & 7) | REX_R(s); 8496 8497 if (s->prefix & PREFIX_DATA) { 8498 ot = MO_16; 8499 } else { 8500 ot = mo_64_32(dflag); 8501 } 8502 8503 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 8504 gen_extu(ot, s->T0); 8505 tcg_gen_mov_tl(cpu_cc_src, s->T0); 8506 tcg_gen_ctpop_tl(s->T0, s->T0); 8507 gen_op_mov_reg_v(s, ot, reg, s->T0); 8508 8509 set_cc_op(s, CC_OP_POPCNT); 8510 break; 8511 case 0x10e ... 0x10f: 8512 /* 3DNow! instructions, ignore prefixes */ 8513 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA); 8514 /* fall through */ 8515 case 0x110 ... 0x117: 8516 case 0x128 ... 0x12f: 8517 case 0x138 ... 0x13a: 8518 case 0x150 ... 0x179: 8519 case 0x17c ... 0x17f: 8520 case 0x1c2: 8521 case 0x1c4 ... 0x1c6: 8522 case 0x1d0 ... 0x1fe: 8523 gen_sse(env, s, b); 8524 break; 8525 default: 8526 goto unknown_op; 8527 } 8528 return true; 8529 illegal_op: 8530 gen_illegal_opcode(s); 8531 return true; 8532 unknown_op: 8533 gen_unknown_opcode(env, s); 8534 return true; 8535 } 8536 8537 void tcg_x86_init(void) 8538 { 8539 static const char reg_names[CPU_NB_REGS][4] = { 8540 #ifdef TARGET_X86_64 8541 [R_EAX] = "rax", 8542 [R_EBX] = "rbx", 8543 [R_ECX] = "rcx", 8544 [R_EDX] = "rdx", 8545 [R_ESI] = "rsi", 8546 [R_EDI] = "rdi", 8547 [R_EBP] = "rbp", 8548 [R_ESP] = "rsp", 8549 [8] = "r8", 8550 [9] = "r9", 8551 [10] = "r10", 8552 [11] = "r11", 8553 [12] = "r12", 8554 [13] = "r13", 8555 [14] = "r14", 8556 [15] = "r15", 8557 #else 8558 [R_EAX] = "eax", 8559 [R_EBX] = "ebx", 8560 [R_ECX] = "ecx", 8561 [R_EDX] = "edx", 8562 [R_ESI] = "esi", 8563 [R_EDI] = "edi", 8564 [R_EBP] = "ebp", 8565 [R_ESP] = "esp", 8566 #endif 8567 }; 8568 static const char eip_name[] = { 8569 #ifdef TARGET_X86_64 8570 "rip" 8571 #else 8572 "eip" 8573 #endif 8574 }; 8575 static const char seg_base_names[6][8] = { 8576 [R_CS] = "cs_base", 8577 [R_DS] = "ds_base", 8578 [R_ES] = "es_base", 8579 [R_FS] = "fs_base", 8580 [R_GS] = "gs_base", 8581 [R_SS] = "ss_base", 8582 }; 8583 static const char bnd_regl_names[4][8] = { 8584 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb" 8585 }; 8586 static const char bnd_regu_names[4][8] = { 8587 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" 8588 }; 8589 int i; 8590 8591 cpu_cc_op = tcg_global_mem_new_i32(cpu_env, 8592 offsetof(CPUX86State, cc_op), "cc_op"); 8593 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst), 8594 "cc_dst"); 8595 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src), 8596 "cc_src"); 8597 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2), 8598 "cc_src2"); 8599 cpu_eip = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, eip), eip_name); 8600 8601 for (i = 0; i < CPU_NB_REGS; ++i) { 8602 cpu_regs[i] = tcg_global_mem_new(cpu_env, 8603 offsetof(CPUX86State, regs[i]), 8604 reg_names[i]); 8605 } 8606 8607 for (i = 0; i < 6; ++i) { 8608 cpu_seg_base[i] 8609 = tcg_global_mem_new(cpu_env, 8610 offsetof(CPUX86State, segs[i].base), 8611 seg_base_names[i]); 8612 } 8613 8614 for (i = 0; i < 4; ++i) { 8615 cpu_bndl[i] 8616 = tcg_global_mem_new_i64(cpu_env, 8617 offsetof(CPUX86State, bnd_regs[i].lb), 8618 bnd_regl_names[i]); 8619 cpu_bndu[i] 8620 = tcg_global_mem_new_i64(cpu_env, 8621 offsetof(CPUX86State, bnd_regs[i].ub), 8622 bnd_regu_names[i]); 8623 } 8624 } 8625 8626 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 8627 { 8628 DisasContext *dc = container_of(dcbase, DisasContext, base); 8629 CPUX86State *env = cpu->env_ptr; 8630 uint32_t flags = dc->base.tb->flags; 8631 uint32_t cflags = tb_cflags(dc->base.tb); 8632 int cpl = (flags >> HF_CPL_SHIFT) & 3; 8633 int iopl = (flags >> IOPL_SHIFT) & 3; 8634 8635 dc->cs_base = dc->base.tb->cs_base; 8636 dc->pc_save = dc->base.pc_next; 8637 dc->flags = flags; 8638 #ifndef CONFIG_USER_ONLY 8639 dc->cpl = cpl; 8640 dc->iopl = iopl; 8641 #endif 8642 8643 /* We make some simplifying assumptions; validate they're correct. */ 8644 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); 8645 g_assert(CPL(dc) == cpl); 8646 g_assert(IOPL(dc) == iopl); 8647 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0)); 8648 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0)); 8649 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0)); 8650 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0)); 8651 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0)); 8652 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0)); 8653 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0)); 8654 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0)); 8655 8656 dc->cc_op = CC_OP_DYNAMIC; 8657 dc->cc_op_dirty = false; 8658 dc->popl_esp_hack = 0; 8659 /* select memory access functions */ 8660 dc->mem_index = 0; 8661 #ifdef CONFIG_SOFTMMU 8662 dc->mem_index = cpu_mmu_index(env, false); 8663 #endif 8664 dc->cpuid_features = env->features[FEAT_1_EDX]; 8665 dc->cpuid_ext_features = env->features[FEAT_1_ECX]; 8666 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; 8667 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; 8668 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; 8669 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX]; 8670 dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; 8671 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || 8672 (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 8673 /* 8674 * If jmp_opt, we want to handle each string instruction individually. 8675 * For icount also disable repz optimization so that each iteration 8676 * is accounted separately. 8677 */ 8678 dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT); 8679 8680 dc->T0 = tcg_temp_new(); 8681 dc->T1 = tcg_temp_new(); 8682 dc->A0 = tcg_temp_new(); 8683 8684 dc->tmp0 = tcg_temp_new(); 8685 dc->tmp1_i64 = tcg_temp_new_i64(); 8686 dc->tmp2_i32 = tcg_temp_new_i32(); 8687 dc->tmp3_i32 = tcg_temp_new_i32(); 8688 dc->tmp4 = tcg_temp_new(); 8689 dc->ptr0 = tcg_temp_new_ptr(); 8690 dc->ptr1 = tcg_temp_new_ptr(); 8691 dc->ptr2 = tcg_temp_new_ptr(); 8692 dc->cc_srcT = tcg_temp_local_new(); 8693 } 8694 8695 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) 8696 { 8697 } 8698 8699 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 8700 { 8701 DisasContext *dc = container_of(dcbase, DisasContext, base); 8702 target_ulong pc_arg = dc->base.pc_next; 8703 8704 dc->prev_insn_end = tcg_last_op(); 8705 if (TARGET_TB_PCREL) { 8706 pc_arg -= dc->cs_base; 8707 pc_arg &= ~TARGET_PAGE_MASK; 8708 } 8709 tcg_gen_insn_start(pc_arg, dc->cc_op); 8710 } 8711 8712 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 8713 { 8714 DisasContext *dc = container_of(dcbase, DisasContext, base); 8715 8716 #ifdef TARGET_VSYSCALL_PAGE 8717 /* 8718 * Detect entry into the vsyscall page and invoke the syscall. 8719 */ 8720 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) { 8721 gen_exception(dc, EXCP_VSYSCALL); 8722 dc->base.pc_next = dc->pc + 1; 8723 return; 8724 } 8725 #endif 8726 8727 if (disas_insn(dc, cpu)) { 8728 target_ulong pc_next = dc->pc; 8729 dc->base.pc_next = pc_next; 8730 8731 if (dc->base.is_jmp == DISAS_NEXT) { 8732 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) { 8733 /* 8734 * If single step mode, we generate only one instruction and 8735 * generate an exception. 8736 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 8737 * the flag and abort the translation to give the irqs a 8738 * chance to happen. 8739 */ 8740 dc->base.is_jmp = DISAS_EOB_NEXT; 8741 } else if (!is_same_page(&dc->base, pc_next)) { 8742 dc->base.is_jmp = DISAS_TOO_MANY; 8743 } 8744 } 8745 } 8746 } 8747 8748 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 8749 { 8750 DisasContext *dc = container_of(dcbase, DisasContext, base); 8751 8752 switch (dc->base.is_jmp) { 8753 case DISAS_NORETURN: 8754 break; 8755 case DISAS_TOO_MANY: 8756 gen_update_cc_op(dc); 8757 gen_jmp_rel_csize(dc, 0, 0); 8758 break; 8759 case DISAS_EOB_NEXT: 8760 gen_update_cc_op(dc); 8761 gen_update_eip_cur(dc); 8762 /* fall through */ 8763 case DISAS_EOB_ONLY: 8764 gen_eob(dc); 8765 break; 8766 case DISAS_EOB_INHIBIT_IRQ: 8767 gen_update_cc_op(dc); 8768 gen_update_eip_cur(dc); 8769 gen_eob_inhibit_irq(dc, true); 8770 break; 8771 case DISAS_JUMP: 8772 gen_jr(dc); 8773 break; 8774 default: 8775 g_assert_not_reached(); 8776 } 8777 } 8778 8779 static void i386_tr_disas_log(const DisasContextBase *dcbase, 8780 CPUState *cpu, FILE *logfile) 8781 { 8782 DisasContext *dc = container_of(dcbase, DisasContext, base); 8783 8784 fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first)); 8785 target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size); 8786 } 8787 8788 static const TranslatorOps i386_tr_ops = { 8789 .init_disas_context = i386_tr_init_disas_context, 8790 .tb_start = i386_tr_tb_start, 8791 .insn_start = i386_tr_insn_start, 8792 .translate_insn = i386_tr_translate_insn, 8793 .tb_stop = i386_tr_tb_stop, 8794 .disas_log = i386_tr_disas_log, 8795 }; 8796 8797 /* generate intermediate code for basic block 'tb'. */ 8798 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns, 8799 target_ulong pc, void *host_pc) 8800 { 8801 DisasContext dc; 8802 8803 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); 8804 } 8805 8806 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, 8807 target_ulong *data) 8808 { 8809 int cc_op = data[1]; 8810 8811 if (TARGET_TB_PCREL) { 8812 env->eip = (env->eip & TARGET_PAGE_MASK) | data[0]; 8813 } else { 8814 env->eip = data[0] - tb->cs_base; 8815 } 8816 if (cc_op != CC_OP_DYNAMIC) { 8817 env->cc_op = cc_op; 8818 } 8819 } 8820