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