1 /* 2 * i386 translation 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 #include "qemu/osdep.h" 20 21 #include "qemu/host-utils.h" 22 #include "cpu.h" 23 #include "disas/disas.h" 24 #include "exec/exec-all.h" 25 #include "tcg/tcg-op.h" 26 #include "tcg/tcg-op-gvec.h" 27 #include "exec/cpu_ldst.h" 28 #include "exec/translator.h" 29 #include "fpu/softfloat.h" 30 31 #include "exec/helper-proto.h" 32 #include "exec/helper-gen.h" 33 #include "helper-tcg.h" 34 35 #include "exec/log.h" 36 37 #define HELPER_H "helper.h" 38 #include "exec/helper-info.c.inc" 39 #undef HELPER_H 40 41 /* Fixes for Windows namespace pollution. */ 42 #undef IN 43 #undef OUT 44 45 #define PREFIX_REPZ 0x01 46 #define PREFIX_REPNZ 0x02 47 #define PREFIX_LOCK 0x04 48 #define PREFIX_DATA 0x08 49 #define PREFIX_ADR 0x10 50 #define PREFIX_VEX 0x20 51 #define PREFIX_REX 0x40 52 53 #ifdef TARGET_X86_64 54 # define ctztl ctz64 55 # define clztl clz64 56 #else 57 # define ctztl ctz32 58 # define clztl clz32 59 #endif 60 61 /* For a switch indexed by MODRM, match all memory operands for a given OP. */ 62 #define CASE_MODRM_MEM_OP(OP) \ 63 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 64 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 65 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7 66 67 #define CASE_MODRM_OP(OP) \ 68 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 69 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 70 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \ 71 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7 72 73 //#define MACRO_TEST 1 74 75 /* global register indexes */ 76 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2; 77 static TCGv cpu_eip; 78 static TCGv_i32 cpu_cc_op; 79 static TCGv cpu_regs[CPU_NB_REGS]; 80 static TCGv cpu_seg_base[6]; 81 static TCGv_i64 cpu_bndl[4]; 82 static TCGv_i64 cpu_bndu[4]; 83 84 typedef struct DisasContext { 85 DisasContextBase base; 86 87 target_ulong pc; /* pc = eip + cs_base */ 88 target_ulong cs_base; /* base of CS segment */ 89 target_ulong pc_save; 90 91 MemOp aflag; 92 MemOp dflag; 93 94 int8_t override; /* -1 if no override, else R_CS, R_DS, etc */ 95 uint8_t prefix; 96 97 bool has_modrm; 98 uint8_t modrm; 99 100 #ifndef CONFIG_USER_ONLY 101 uint8_t cpl; /* code priv level */ 102 uint8_t iopl; /* i/o priv level */ 103 #endif 104 uint8_t vex_l; /* vex vector length */ 105 uint8_t vex_v; /* vex vvvv register, without 1's complement. */ 106 uint8_t popl_esp_hack; /* for correct popl with esp base handling */ 107 uint8_t rip_offset; /* only used in x86_64, but left for simplicity */ 108 109 #ifdef TARGET_X86_64 110 uint8_t rex_r; 111 uint8_t rex_x; 112 uint8_t rex_b; 113 #endif 114 bool vex_w; /* used by AVX even on 32-bit processors */ 115 bool jmp_opt; /* use direct block chaining for direct jumps */ 116 bool repz_opt; /* optimize jumps within repz instructions */ 117 bool cc_op_dirty; 118 119 CCOp cc_op; /* current CC operation */ 120 int mem_index; /* select memory access functions */ 121 uint32_t flags; /* all execution flags */ 122 int cpuid_features; 123 int cpuid_ext_features; 124 int cpuid_ext2_features; 125 int cpuid_ext3_features; 126 int cpuid_7_0_ebx_features; 127 int cpuid_7_0_ecx_features; 128 int cpuid_7_1_eax_features; 129 int cpuid_xsave_features; 130 131 /* TCG local temps */ 132 TCGv cc_srcT; 133 TCGv A0; 134 TCGv T0; 135 TCGv T1; 136 137 /* TCG local register indexes (only used inside old micro ops) */ 138 TCGv tmp0; 139 TCGv tmp4; 140 TCGv_i32 tmp2_i32; 141 TCGv_i32 tmp3_i32; 142 TCGv_i64 tmp1_i64; 143 144 sigjmp_buf jmpbuf; 145 TCGOp *prev_insn_start; 146 TCGOp *prev_insn_end; 147 } DisasContext; 148 149 #define DISAS_EOB_ONLY DISAS_TARGET_0 150 #define DISAS_EOB_NEXT DISAS_TARGET_1 151 #define DISAS_EOB_INHIBIT_IRQ DISAS_TARGET_2 152 #define DISAS_JUMP DISAS_TARGET_3 153 154 /* The environment in which user-only runs is constrained. */ 155 #ifdef CONFIG_USER_ONLY 156 #define PE(S) true 157 #define CPL(S) 3 158 #define IOPL(S) 0 159 #define SVME(S) false 160 #define GUEST(S) false 161 #else 162 #define PE(S) (((S)->flags & HF_PE_MASK) != 0) 163 #define CPL(S) ((S)->cpl) 164 #define IOPL(S) ((S)->iopl) 165 #define SVME(S) (((S)->flags & HF_SVME_MASK) != 0) 166 #define GUEST(S) (((S)->flags & HF_GUEST_MASK) != 0) 167 #endif 168 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64) 169 #define VM86(S) false 170 #define CODE32(S) true 171 #define SS32(S) true 172 #define ADDSEG(S) false 173 #else 174 #define VM86(S) (((S)->flags & HF_VM_MASK) != 0) 175 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0) 176 #define SS32(S) (((S)->flags & HF_SS32_MASK) != 0) 177 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0) 178 #endif 179 #if !defined(TARGET_X86_64) 180 #define CODE64(S) false 181 #elif defined(CONFIG_USER_ONLY) 182 #define CODE64(S) true 183 #else 184 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0) 185 #endif 186 #if defined(CONFIG_USER_ONLY) || defined(TARGET_X86_64) 187 #define LMA(S) (((S)->flags & HF_LMA_MASK) != 0) 188 #else 189 #define LMA(S) false 190 #endif 191 192 #ifdef TARGET_X86_64 193 #define REX_PREFIX(S) (((S)->prefix & PREFIX_REX) != 0) 194 #define REX_W(S) ((S)->vex_w) 195 #define REX_R(S) ((S)->rex_r + 0) 196 #define REX_X(S) ((S)->rex_x + 0) 197 #define REX_B(S) ((S)->rex_b + 0) 198 #else 199 #define REX_PREFIX(S) false 200 #define REX_W(S) false 201 #define REX_R(S) 0 202 #define REX_X(S) 0 203 #define REX_B(S) 0 204 #endif 205 206 /* 207 * Many sysemu-only helpers are not reachable for user-only. 208 * Define stub generators here, so that we need not either sprinkle 209 * ifdefs through the translator, nor provide the helper function. 210 */ 211 #define STUB_HELPER(NAME, ...) \ 212 static inline void gen_helper_##NAME(__VA_ARGS__) \ 213 { qemu_build_not_reached(); } 214 215 #ifdef CONFIG_USER_ONLY 216 STUB_HELPER(clgi, TCGv_env env) 217 STUB_HELPER(flush_page, TCGv_env env, TCGv addr) 218 STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port) 219 STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port) 220 STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port) 221 STUB_HELPER(monitor, TCGv_env env, TCGv addr) 222 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs) 223 STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 224 STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 225 STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 226 STUB_HELPER(rdmsr, TCGv_env env) 227 STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg) 228 STUB_HELPER(get_dr, TCGv ret, TCGv_env env, TCGv_i32 reg) 229 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val) 230 STUB_HELPER(stgi, TCGv_env env) 231 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type) 232 STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag) 233 STUB_HELPER(vmmcall, TCGv_env env) 234 STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs) 235 STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag) 236 STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val) 237 STUB_HELPER(wrmsr, TCGv_env env) 238 #endif 239 240 static void gen_eob(DisasContext *s); 241 static void gen_jr(DisasContext *s); 242 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num); 243 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num); 244 static void gen_exception_gpf(DisasContext *s); 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 size 8 if lsb of B is clear, else OT. Used for decoding 415 byte vs word opcodes. */ 416 static inline MemOp mo_b_d(int b, MemOp ot) 417 { 418 return b & 1 ? ot : MO_8; 419 } 420 421 /* Compute the result of writing t0 to the OT-sized register REG. 422 * 423 * If DEST is NULL, store the result into the register and return the 424 * register's TCGv. 425 * 426 * If DEST is not NULL, store the result into DEST and return the 427 * register's TCGv. 428 */ 429 static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest, TCGv t0) 430 { 431 switch(ot) { 432 case MO_8: 433 if (byte_reg_is_xH(s, reg)) { 434 dest = dest ? dest : cpu_regs[reg - 4]; 435 tcg_gen_deposit_tl(dest, cpu_regs[reg - 4], t0, 8, 8); 436 return cpu_regs[reg - 4]; 437 } 438 dest = dest ? dest : cpu_regs[reg]; 439 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 8); 440 break; 441 case MO_16: 442 dest = dest ? dest : cpu_regs[reg]; 443 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 16); 444 break; 445 case MO_32: 446 /* For x86_64, this sets the higher half of register to zero. 447 For i386, this is equivalent to a mov. */ 448 dest = dest ? dest : cpu_regs[reg]; 449 tcg_gen_ext32u_tl(dest, t0); 450 break; 451 #ifdef TARGET_X86_64 452 case MO_64: 453 dest = dest ? dest : cpu_regs[reg]; 454 tcg_gen_mov_tl(dest, t0); 455 break; 456 #endif 457 default: 458 g_assert_not_reached(); 459 } 460 return cpu_regs[reg]; 461 } 462 463 static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0) 464 { 465 gen_op_deposit_reg_v(s, ot, reg, NULL, t0); 466 } 467 468 static inline 469 void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg) 470 { 471 if (ot == MO_8 && byte_reg_is_xH(s, reg)) { 472 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8); 473 } else { 474 tcg_gen_mov_tl(t0, cpu_regs[reg]); 475 } 476 } 477 478 static void gen_add_A0_im(DisasContext *s, int val) 479 { 480 tcg_gen_addi_tl(s->A0, s->A0, val); 481 if (!CODE64(s)) { 482 tcg_gen_ext32u_tl(s->A0, s->A0); 483 } 484 } 485 486 static inline void gen_op_jmp_v(DisasContext *s, TCGv dest) 487 { 488 tcg_gen_mov_tl(cpu_eip, dest); 489 s->pc_save = -1; 490 } 491 492 static inline 493 void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val) 494 { 495 tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val); 496 gen_op_mov_reg_v(s, size, reg, s->tmp0); 497 } 498 499 static inline void gen_op_add_reg(DisasContext *s, MemOp size, int reg, TCGv val) 500 { 501 tcg_gen_add_tl(s->tmp0, cpu_regs[reg], val); 502 gen_op_mov_reg_v(s, size, reg, s->tmp0); 503 } 504 505 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 506 { 507 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE); 508 } 509 510 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 511 { 512 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE); 513 } 514 515 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d) 516 { 517 if (d == OR_TMP0) { 518 gen_op_st_v(s, idx, s->T0, s->A0); 519 } else { 520 gen_op_mov_reg_v(s, idx, d, s->T0); 521 } 522 } 523 524 static void gen_update_eip_cur(DisasContext *s) 525 { 526 assert(s->pc_save != -1); 527 if (tb_cflags(s->base.tb) & CF_PCREL) { 528 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save); 529 } else if (CODE64(s)) { 530 tcg_gen_movi_tl(cpu_eip, s->base.pc_next); 531 } else { 532 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->base.pc_next - s->cs_base)); 533 } 534 s->pc_save = s->base.pc_next; 535 } 536 537 static void gen_update_eip_next(DisasContext *s) 538 { 539 assert(s->pc_save != -1); 540 if (tb_cflags(s->base.tb) & CF_PCREL) { 541 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save); 542 } else if (CODE64(s)) { 543 tcg_gen_movi_tl(cpu_eip, s->pc); 544 } else { 545 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->pc - s->cs_base)); 546 } 547 s->pc_save = s->pc; 548 } 549 550 static int cur_insn_len(DisasContext *s) 551 { 552 return s->pc - s->base.pc_next; 553 } 554 555 static TCGv_i32 cur_insn_len_i32(DisasContext *s) 556 { 557 return tcg_constant_i32(cur_insn_len(s)); 558 } 559 560 static TCGv_i32 eip_next_i32(DisasContext *s) 561 { 562 assert(s->pc_save != -1); 563 /* 564 * This function has two users: lcall_real (always 16-bit mode), and 565 * iret_protected (16, 32, or 64-bit mode). IRET only uses the value 566 * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is 567 * why passing a 32-bit value isn't broken. To avoid using this where 568 * we shouldn't, return -1 in 64-bit mode so that execution goes into 569 * the weeds quickly. 570 */ 571 if (CODE64(s)) { 572 return tcg_constant_i32(-1); 573 } 574 if (tb_cflags(s->base.tb) & CF_PCREL) { 575 TCGv_i32 ret = tcg_temp_new_i32(); 576 tcg_gen_trunc_tl_i32(ret, cpu_eip); 577 tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save); 578 return ret; 579 } else { 580 return tcg_constant_i32(s->pc - s->cs_base); 581 } 582 } 583 584 static TCGv eip_next_tl(DisasContext *s) 585 { 586 assert(s->pc_save != -1); 587 if (tb_cflags(s->base.tb) & CF_PCREL) { 588 TCGv ret = tcg_temp_new(); 589 tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save); 590 return ret; 591 } else if (CODE64(s)) { 592 return tcg_constant_tl(s->pc); 593 } else { 594 return tcg_constant_tl((uint32_t)(s->pc - s->cs_base)); 595 } 596 } 597 598 static TCGv eip_cur_tl(DisasContext *s) 599 { 600 assert(s->pc_save != -1); 601 if (tb_cflags(s->base.tb) & CF_PCREL) { 602 TCGv ret = tcg_temp_new(); 603 tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save); 604 return ret; 605 } else if (CODE64(s)) { 606 return tcg_constant_tl(s->base.pc_next); 607 } else { 608 return tcg_constant_tl((uint32_t)(s->base.pc_next - s->cs_base)); 609 } 610 } 611 612 /* Compute SEG:REG into DEST. SEG is selected from the override segment 613 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to 614 indicate no override. */ 615 static void gen_lea_v_seg_dest(DisasContext *s, MemOp aflag, TCGv dest, TCGv a0, 616 int def_seg, int ovr_seg) 617 { 618 switch (aflag) { 619 #ifdef TARGET_X86_64 620 case MO_64: 621 if (ovr_seg < 0) { 622 tcg_gen_mov_tl(dest, a0); 623 return; 624 } 625 break; 626 #endif 627 case MO_32: 628 /* 32 bit address */ 629 if (ovr_seg < 0 && ADDSEG(s)) { 630 ovr_seg = def_seg; 631 } 632 if (ovr_seg < 0) { 633 tcg_gen_ext32u_tl(dest, a0); 634 return; 635 } 636 break; 637 case MO_16: 638 /* 16 bit address */ 639 tcg_gen_ext16u_tl(dest, a0); 640 a0 = dest; 641 if (ovr_seg < 0) { 642 if (ADDSEG(s)) { 643 ovr_seg = def_seg; 644 } else { 645 return; 646 } 647 } 648 break; 649 default: 650 g_assert_not_reached(); 651 } 652 653 if (ovr_seg >= 0) { 654 TCGv seg = cpu_seg_base[ovr_seg]; 655 656 if (aflag == MO_64) { 657 tcg_gen_add_tl(dest, a0, seg); 658 } else if (CODE64(s)) { 659 tcg_gen_ext32u_tl(dest, a0); 660 tcg_gen_add_tl(dest, dest, seg); 661 } else { 662 tcg_gen_add_tl(dest, a0, seg); 663 tcg_gen_ext32u_tl(dest, dest); 664 } 665 } 666 } 667 668 static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0, 669 int def_seg, int ovr_seg) 670 { 671 gen_lea_v_seg_dest(s, aflag, s->A0, a0, def_seg, ovr_seg); 672 } 673 674 static inline void gen_string_movl_A0_ESI(DisasContext *s) 675 { 676 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override); 677 } 678 679 static inline void gen_string_movl_A0_EDI(DisasContext *s) 680 { 681 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1); 682 } 683 684 static inline TCGv gen_compute_Dshift(DisasContext *s, MemOp ot) 685 { 686 TCGv dshift = tcg_temp_new(); 687 tcg_gen_ld32s_tl(dshift, tcg_env, offsetof(CPUX86State, df)); 688 tcg_gen_shli_tl(dshift, dshift, ot); 689 return dshift; 690 }; 691 692 static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign) 693 { 694 if (size == MO_TL) { 695 return src; 696 } 697 if (!dst) { 698 dst = tcg_temp_new(); 699 } 700 tcg_gen_ext_tl(dst, src, size | (sign ? MO_SIGN : 0)); 701 return dst; 702 } 703 704 static void gen_extu(MemOp ot, TCGv reg) 705 { 706 gen_ext_tl(reg, reg, ot, false); 707 } 708 709 static void gen_exts(MemOp ot, TCGv reg) 710 { 711 gen_ext_tl(reg, reg, ot, true); 712 } 713 714 static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1) 715 { 716 TCGv tmp = gen_ext_tl(NULL, cpu_regs[R_ECX], s->aflag, false); 717 718 tcg_gen_brcondi_tl(cond, tmp, 0, label1); 719 } 720 721 static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1) 722 { 723 gen_op_j_ecx(s, TCG_COND_EQ, label1); 724 } 725 726 static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1) 727 { 728 gen_op_j_ecx(s, TCG_COND_NE, label1); 729 } 730 731 static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n) 732 { 733 switch (ot) { 734 case MO_8: 735 gen_helper_inb(v, tcg_env, n); 736 break; 737 case MO_16: 738 gen_helper_inw(v, tcg_env, n); 739 break; 740 case MO_32: 741 gen_helper_inl(v, tcg_env, n); 742 break; 743 default: 744 g_assert_not_reached(); 745 } 746 } 747 748 static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n) 749 { 750 switch (ot) { 751 case MO_8: 752 gen_helper_outb(tcg_env, v, n); 753 break; 754 case MO_16: 755 gen_helper_outw(tcg_env, v, n); 756 break; 757 case MO_32: 758 gen_helper_outl(tcg_env, v, n); 759 break; 760 default: 761 g_assert_not_reached(); 762 } 763 } 764 765 /* 766 * Validate that access to [port, port + 1<<ot) is allowed. 767 * Raise #GP, or VMM exit if not. 768 */ 769 static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port, 770 uint32_t svm_flags) 771 { 772 #ifdef CONFIG_USER_ONLY 773 /* 774 * We do not implement the ioperm(2) syscall, so the TSS check 775 * will always fail. 776 */ 777 gen_exception_gpf(s); 778 return false; 779 #else 780 if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) { 781 gen_helper_check_io(tcg_env, port, tcg_constant_i32(1 << ot)); 782 } 783 if (GUEST(s)) { 784 gen_update_cc_op(s); 785 gen_update_eip_cur(s); 786 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) { 787 svm_flags |= SVM_IOIO_REP_MASK; 788 } 789 svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot); 790 gen_helper_svm_check_io(tcg_env, port, 791 tcg_constant_i32(svm_flags), 792 cur_insn_len_i32(s)); 793 } 794 return true; 795 #endif 796 } 797 798 static void gen_movs(DisasContext *s, MemOp ot) 799 { 800 TCGv dshift; 801 802 gen_string_movl_A0_ESI(s); 803 gen_op_ld_v(s, ot, s->T0, s->A0); 804 gen_string_movl_A0_EDI(s); 805 gen_op_st_v(s, ot, s->T0, s->A0); 806 807 dshift = gen_compute_Dshift(s, ot); 808 gen_op_add_reg(s, s->aflag, R_ESI, dshift); 809 gen_op_add_reg(s, s->aflag, R_EDI, dshift); 810 } 811 812 static void gen_op_update1_cc(DisasContext *s) 813 { 814 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 815 } 816 817 static void gen_op_update2_cc(DisasContext *s) 818 { 819 tcg_gen_mov_tl(cpu_cc_src, s->T1); 820 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 821 } 822 823 /* compute all eflags to reg */ 824 static void gen_mov_eflags(DisasContext *s, TCGv reg) 825 { 826 TCGv dst, src1, src2; 827 TCGv_i32 cc_op; 828 int live, dead; 829 830 if (s->cc_op == CC_OP_EFLAGS) { 831 tcg_gen_mov_tl(reg, cpu_cc_src); 832 return; 833 } 834 if (s->cc_op == CC_OP_CLR) { 835 tcg_gen_movi_tl(reg, CC_Z | CC_P); 836 return; 837 } 838 839 dst = cpu_cc_dst; 840 src1 = cpu_cc_src; 841 src2 = cpu_cc_src2; 842 843 /* Take care to not read values that are not live. */ 844 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT; 845 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2); 846 if (dead) { 847 TCGv zero = tcg_constant_tl(0); 848 if (dead & USES_CC_DST) { 849 dst = zero; 850 } 851 if (dead & USES_CC_SRC) { 852 src1 = zero; 853 } 854 if (dead & USES_CC_SRC2) { 855 src2 = zero; 856 } 857 } 858 859 if (s->cc_op != CC_OP_DYNAMIC) { 860 cc_op = tcg_constant_i32(s->cc_op); 861 } else { 862 cc_op = cpu_cc_op; 863 } 864 gen_helper_cc_compute_all(reg, dst, src1, src2, cc_op); 865 } 866 867 /* compute all eflags to cc_src */ 868 static void gen_compute_eflags(DisasContext *s) 869 { 870 gen_mov_eflags(s, cpu_cc_src); 871 set_cc_op(s, CC_OP_EFLAGS); 872 } 873 874 typedef struct CCPrepare { 875 TCGCond cond; 876 TCGv reg; 877 TCGv reg2; 878 target_ulong imm; 879 bool use_reg2; 880 bool no_setcond; 881 } CCPrepare; 882 883 static CCPrepare gen_prepare_sign_nz(TCGv src, MemOp size) 884 { 885 if (size == MO_TL) { 886 return (CCPrepare) { .cond = TCG_COND_LT, .reg = src }; 887 } else { 888 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = src, 889 .imm = 1ull << ((8 << size) - 1) }; 890 } 891 } 892 893 /* compute eflags.C, trying to store it in reg if not NULL */ 894 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg) 895 { 896 MemOp size; 897 898 switch (s->cc_op) { 899 case CC_OP_SUBB ... CC_OP_SUBQ: 900 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */ 901 size = s->cc_op - CC_OP_SUBB; 902 gen_ext_tl(s->cc_srcT, s->cc_srcT, size, false); 903 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 904 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = s->cc_srcT, 905 .reg2 = cpu_cc_src, .use_reg2 = true }; 906 907 case CC_OP_ADDB ... CC_OP_ADDQ: 908 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */ 909 size = s->cc_op - CC_OP_ADDB; 910 gen_ext_tl(cpu_cc_dst, cpu_cc_dst, size, false); 911 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 912 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = cpu_cc_dst, 913 .reg2 = cpu_cc_src, .use_reg2 = true }; 914 915 case CC_OP_LOGICB ... CC_OP_LOGICQ: 916 case CC_OP_CLR: 917 case CC_OP_POPCNT: 918 return (CCPrepare) { .cond = TCG_COND_NEVER }; 919 920 case CC_OP_INCB ... CC_OP_INCQ: 921 case CC_OP_DECB ... CC_OP_DECQ: 922 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 923 .no_setcond = true }; 924 925 case CC_OP_SHLB ... CC_OP_SHLQ: 926 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */ 927 size = s->cc_op - CC_OP_SHLB; 928 return gen_prepare_sign_nz(cpu_cc_src, size); 929 930 case CC_OP_MULB ... CC_OP_MULQ: 931 return (CCPrepare) { .cond = TCG_COND_NE, 932 .reg = cpu_cc_src }; 933 934 case CC_OP_BMILGB ... CC_OP_BMILGQ: 935 size = s->cc_op - CC_OP_BMILGB; 936 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 937 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src }; 938 939 case CC_OP_ADCX: 940 case CC_OP_ADCOX: 941 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst, 942 .no_setcond = true }; 943 944 case CC_OP_EFLAGS: 945 case CC_OP_SARB ... CC_OP_SARQ: 946 /* CC_SRC & 1 */ 947 return (CCPrepare) { .cond = TCG_COND_TSTNE, 948 .reg = cpu_cc_src, .imm = CC_C }; 949 950 default: 951 /* The need to compute only C from CC_OP_DYNAMIC is important 952 in efficiently implementing e.g. INC at the start of a TB. */ 953 gen_update_cc_op(s); 954 if (!reg) { 955 reg = tcg_temp_new(); 956 } 957 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src, 958 cpu_cc_src2, cpu_cc_op); 959 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg, 960 .no_setcond = true }; 961 } 962 } 963 964 /* compute eflags.P, trying to store it in reg if not NULL */ 965 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg) 966 { 967 gen_compute_eflags(s); 968 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 969 .imm = CC_P }; 970 } 971 972 /* compute eflags.S, trying to store it in reg if not NULL */ 973 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg) 974 { 975 switch (s->cc_op) { 976 case CC_OP_DYNAMIC: 977 gen_compute_eflags(s); 978 /* FALLTHRU */ 979 case CC_OP_EFLAGS: 980 case CC_OP_ADCX: 981 case CC_OP_ADOX: 982 case CC_OP_ADCOX: 983 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 984 .imm = CC_S }; 985 case CC_OP_CLR: 986 case CC_OP_POPCNT: 987 return (CCPrepare) { .cond = TCG_COND_NEVER }; 988 default: 989 { 990 MemOp size = (s->cc_op - CC_OP_ADDB) & 3; 991 return gen_prepare_sign_nz(cpu_cc_dst, size); 992 } 993 } 994 } 995 996 /* compute eflags.O, trying to store it in reg if not NULL */ 997 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg) 998 { 999 switch (s->cc_op) { 1000 case CC_OP_ADOX: 1001 case CC_OP_ADCOX: 1002 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2, 1003 .no_setcond = true }; 1004 case CC_OP_CLR: 1005 case CC_OP_POPCNT: 1006 return (CCPrepare) { .cond = TCG_COND_NEVER }; 1007 case CC_OP_MULB ... CC_OP_MULQ: 1008 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src }; 1009 default: 1010 gen_compute_eflags(s); 1011 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1012 .imm = CC_O }; 1013 } 1014 } 1015 1016 /* compute eflags.Z, trying to store it in reg if not NULL */ 1017 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg) 1018 { 1019 switch (s->cc_op) { 1020 case CC_OP_DYNAMIC: 1021 gen_compute_eflags(s); 1022 /* FALLTHRU */ 1023 case CC_OP_EFLAGS: 1024 case CC_OP_ADCX: 1025 case CC_OP_ADOX: 1026 case CC_OP_ADCOX: 1027 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1028 .imm = CC_Z }; 1029 case CC_OP_CLR: 1030 return (CCPrepare) { .cond = TCG_COND_ALWAYS }; 1031 case CC_OP_POPCNT: 1032 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src }; 1033 default: 1034 { 1035 MemOp size = (s->cc_op - CC_OP_ADDB) & 3; 1036 if (size == MO_TL) { 1037 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_dst }; 1038 } else { 1039 return (CCPrepare) { .cond = TCG_COND_TSTEQ, .reg = cpu_cc_dst, 1040 .imm = (1ull << (8 << size)) - 1 }; 1041 } 1042 } 1043 } 1044 } 1045 1046 /* return how to compute jump opcode 'b'. 'reg' can be clobbered 1047 * if needed; it may be used for CCPrepare.reg if that will 1048 * provide more freedom in the translation of a subsequent setcond. */ 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 1055 inv = b & 1; 1056 jcc_op = (b >> 1) & 7; 1057 1058 switch (s->cc_op) { 1059 case CC_OP_SUBB ... CC_OP_SUBQ: 1060 /* We optimize relational operators for the cmp/jcc case. */ 1061 size = s->cc_op - CC_OP_SUBB; 1062 switch (jcc_op) { 1063 case JCC_BE: 1064 gen_ext_tl(s->cc_srcT, s->cc_srcT, size, false); 1065 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 1066 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->cc_srcT, 1067 .reg2 = cpu_cc_src, .use_reg2 = true }; 1068 break; 1069 case JCC_L: 1070 cond = TCG_COND_LT; 1071 goto fast_jcc_l; 1072 case JCC_LE: 1073 cond = TCG_COND_LE; 1074 fast_jcc_l: 1075 gen_ext_tl(s->cc_srcT, s->cc_srcT, size, true); 1076 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, true); 1077 cc = (CCPrepare) { .cond = cond, .reg = s->cc_srcT, 1078 .reg2 = cpu_cc_src, .use_reg2 = true }; 1079 break; 1080 1081 default: 1082 goto slow_jcc; 1083 } 1084 break; 1085 1086 default: 1087 slow_jcc: 1088 /* This actually generates good code for JC, JZ and JS. */ 1089 switch (jcc_op) { 1090 case JCC_O: 1091 cc = gen_prepare_eflags_o(s, reg); 1092 break; 1093 case JCC_B: 1094 cc = gen_prepare_eflags_c(s, reg); 1095 break; 1096 case JCC_Z: 1097 cc = gen_prepare_eflags_z(s, reg); 1098 break; 1099 case JCC_BE: 1100 gen_compute_eflags(s); 1101 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1102 .imm = CC_Z | CC_C }; 1103 break; 1104 case JCC_S: 1105 cc = gen_prepare_eflags_s(s, reg); 1106 break; 1107 case JCC_P: 1108 cc = gen_prepare_eflags_p(s, reg); 1109 break; 1110 case JCC_L: 1111 gen_compute_eflags(s); 1112 if (!reg || reg == cpu_cc_src) { 1113 reg = tcg_temp_new(); 1114 } 1115 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S); 1116 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg, 1117 .imm = CC_O }; 1118 break; 1119 default: 1120 case JCC_LE: 1121 gen_compute_eflags(s); 1122 if (!reg || reg == cpu_cc_src) { 1123 reg = tcg_temp_new(); 1124 } 1125 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S); 1126 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg, 1127 .imm = CC_O | CC_Z }; 1128 break; 1129 } 1130 break; 1131 } 1132 1133 if (inv) { 1134 cc.cond = tcg_invert_cond(cc.cond); 1135 } 1136 return cc; 1137 } 1138 1139 static void gen_setcc1(DisasContext *s, int b, TCGv reg) 1140 { 1141 CCPrepare cc = gen_prepare_cc(s, b, reg); 1142 1143 if (cc.no_setcond) { 1144 if (cc.cond == TCG_COND_EQ) { 1145 tcg_gen_xori_tl(reg, cc.reg, 1); 1146 } else { 1147 tcg_gen_mov_tl(reg, cc.reg); 1148 } 1149 return; 1150 } 1151 1152 if (cc.use_reg2) { 1153 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2); 1154 } else { 1155 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm); 1156 } 1157 } 1158 1159 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg) 1160 { 1161 gen_setcc1(s, JCC_B << 1, reg); 1162 } 1163 1164 /* generate a conditional jump to label 'l1' according to jump opcode 1165 value 'b'. In the fast case, T0 is guaranteed not to be used. */ 1166 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1) 1167 { 1168 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1169 1170 if (cc.use_reg2) { 1171 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1172 } else { 1173 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1174 } 1175 } 1176 1177 /* Generate a conditional jump to label 'l1' according to jump opcode 1178 value 'b'. In the fast case, T0 is guaranteed not to be used. 1179 One or both of the branches will call gen_jmp_rel, so ensure 1180 cc_op is clean. */ 1181 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1) 1182 { 1183 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1184 1185 gen_update_cc_op(s); 1186 if (cc.use_reg2) { 1187 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1188 } else { 1189 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1190 } 1191 } 1192 1193 /* XXX: does not work with gdbstub "ice" single step - not a 1194 serious problem. The caller can jump to the returned label 1195 to stop the REP but, if the flags have changed, it has to call 1196 gen_update_cc_op before doing so. */ 1197 static TCGLabel *gen_jz_ecx_string(DisasContext *s) 1198 { 1199 TCGLabel *l1 = gen_new_label(); 1200 TCGLabel *l2 = gen_new_label(); 1201 1202 gen_update_cc_op(s); 1203 gen_op_jnz_ecx(s, l1); 1204 gen_set_label(l2); 1205 gen_jmp_rel_csize(s, 0, 1); 1206 gen_set_label(l1); 1207 return l2; 1208 } 1209 1210 static void gen_stos(DisasContext *s, MemOp ot) 1211 { 1212 gen_string_movl_A0_EDI(s); 1213 gen_op_st_v(s, ot, s->T0, s->A0); 1214 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot)); 1215 } 1216 1217 static void gen_lods(DisasContext *s, MemOp ot) 1218 { 1219 gen_string_movl_A0_ESI(s); 1220 gen_op_ld_v(s, ot, s->T0, s->A0); 1221 gen_op_mov_reg_v(s, ot, R_EAX, s->T0); 1222 gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot)); 1223 } 1224 1225 static void gen_scas(DisasContext *s, MemOp ot) 1226 { 1227 gen_string_movl_A0_EDI(s); 1228 gen_op_ld_v(s, ot, s->T1, s->A0); 1229 tcg_gen_mov_tl(cpu_cc_src, s->T1); 1230 tcg_gen_mov_tl(s->cc_srcT, s->T0); 1231 tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1); 1232 set_cc_op(s, CC_OP_SUBB + ot); 1233 1234 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot)); 1235 } 1236 1237 static void gen_cmps(DisasContext *s, MemOp ot) 1238 { 1239 TCGv dshift; 1240 1241 gen_string_movl_A0_EDI(s); 1242 gen_op_ld_v(s, ot, s->T1, s->A0); 1243 gen_string_movl_A0_ESI(s); 1244 gen_op_ld_v(s, ot, s->T0, s->A0); 1245 tcg_gen_mov_tl(cpu_cc_src, s->T1); 1246 tcg_gen_mov_tl(s->cc_srcT, s->T0); 1247 tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1); 1248 set_cc_op(s, CC_OP_SUBB + ot); 1249 1250 dshift = gen_compute_Dshift(s, ot); 1251 gen_op_add_reg(s, s->aflag, R_ESI, dshift); 1252 gen_op_add_reg(s, s->aflag, R_EDI, dshift); 1253 } 1254 1255 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot) 1256 { 1257 if (s->flags & HF_IOBPT_MASK) { 1258 #ifdef CONFIG_USER_ONLY 1259 /* user-mode cpu should not be in IOBPT mode */ 1260 g_assert_not_reached(); 1261 #else 1262 TCGv_i32 t_size = tcg_constant_i32(1 << ot); 1263 TCGv t_next = eip_next_tl(s); 1264 gen_helper_bpt_io(tcg_env, t_port, t_size, t_next); 1265 #endif /* CONFIG_USER_ONLY */ 1266 } 1267 } 1268 1269 static void gen_ins(DisasContext *s, MemOp ot) 1270 { 1271 gen_string_movl_A0_EDI(s); 1272 /* Note: we must do this dummy write first to be restartable in 1273 case of page fault. */ 1274 tcg_gen_movi_tl(s->T0, 0); 1275 gen_op_st_v(s, ot, s->T0, s->A0); 1276 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 1277 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); 1278 gen_helper_in_func(ot, s->T0, s->tmp2_i32); 1279 gen_op_st_v(s, ot, s->T0, s->A0); 1280 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot)); 1281 gen_bpt_io(s, s->tmp2_i32, ot); 1282 } 1283 1284 static void gen_outs(DisasContext *s, MemOp ot) 1285 { 1286 gen_string_movl_A0_ESI(s); 1287 gen_op_ld_v(s, ot, s->T0, s->A0); 1288 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 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0); 1292 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 1293 gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot)); 1294 gen_bpt_io(s, s->tmp2_i32, ot); 1295 } 1296 1297 /* Generate jumps to current or next instruction */ 1298 static void gen_repz(DisasContext *s, MemOp ot, 1299 void (*fn)(DisasContext *s, MemOp ot)) 1300 { 1301 TCGLabel *l2; 1302 l2 = gen_jz_ecx_string(s); 1303 fn(s, ot); 1304 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 1305 /* 1306 * A loop would cause two single step exceptions if ECX = 1 1307 * before rep string_insn 1308 */ 1309 if (s->repz_opt) { 1310 gen_op_jz_ecx(s, l2); 1311 } 1312 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1313 } 1314 1315 #define GEN_REPZ(op) \ 1316 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot) \ 1317 { gen_repz(s, ot, gen_##op); } 1318 1319 static void gen_repz2(DisasContext *s, MemOp ot, int nz, 1320 void (*fn)(DisasContext *s, MemOp ot)) 1321 { 1322 TCGLabel *l2; 1323 l2 = gen_jz_ecx_string(s); 1324 fn(s, ot); 1325 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 1326 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); 1327 if (s->repz_opt) { 1328 gen_op_jz_ecx(s, l2); 1329 } 1330 /* 1331 * Only one iteration is done at a time, so the translation 1332 * block ends unconditionally after this instruction and there 1333 * is no control flow junction - no need to set CC_OP_DYNAMIC. 1334 */ 1335 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1336 } 1337 1338 #define GEN_REPZ2(op) \ 1339 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, int nz) \ 1340 { gen_repz2(s, ot, nz, gen_##op); } 1341 1342 GEN_REPZ(movs) 1343 GEN_REPZ(stos) 1344 GEN_REPZ(lods) 1345 GEN_REPZ(ins) 1346 GEN_REPZ(outs) 1347 GEN_REPZ2(scas) 1348 GEN_REPZ2(cmps) 1349 1350 static void gen_helper_fp_arith_ST0_FT0(int op) 1351 { 1352 switch (op) { 1353 case 0: 1354 gen_helper_fadd_ST0_FT0(tcg_env); 1355 break; 1356 case 1: 1357 gen_helper_fmul_ST0_FT0(tcg_env); 1358 break; 1359 case 2: 1360 gen_helper_fcom_ST0_FT0(tcg_env); 1361 break; 1362 case 3: 1363 gen_helper_fcom_ST0_FT0(tcg_env); 1364 break; 1365 case 4: 1366 gen_helper_fsub_ST0_FT0(tcg_env); 1367 break; 1368 case 5: 1369 gen_helper_fsubr_ST0_FT0(tcg_env); 1370 break; 1371 case 6: 1372 gen_helper_fdiv_ST0_FT0(tcg_env); 1373 break; 1374 case 7: 1375 gen_helper_fdivr_ST0_FT0(tcg_env); 1376 break; 1377 } 1378 } 1379 1380 /* NOTE the exception in "r" op ordering */ 1381 static void gen_helper_fp_arith_STN_ST0(int op, int opreg) 1382 { 1383 TCGv_i32 tmp = tcg_constant_i32(opreg); 1384 switch (op) { 1385 case 0: 1386 gen_helper_fadd_STN_ST0(tcg_env, tmp); 1387 break; 1388 case 1: 1389 gen_helper_fmul_STN_ST0(tcg_env, tmp); 1390 break; 1391 case 4: 1392 gen_helper_fsubr_STN_ST0(tcg_env, tmp); 1393 break; 1394 case 5: 1395 gen_helper_fsub_STN_ST0(tcg_env, tmp); 1396 break; 1397 case 6: 1398 gen_helper_fdivr_STN_ST0(tcg_env, tmp); 1399 break; 1400 case 7: 1401 gen_helper_fdiv_STN_ST0(tcg_env, tmp); 1402 break; 1403 } 1404 } 1405 1406 static void gen_exception(DisasContext *s, int trapno) 1407 { 1408 gen_update_cc_op(s); 1409 gen_update_eip_cur(s); 1410 gen_helper_raise_exception(tcg_env, tcg_constant_i32(trapno)); 1411 s->base.is_jmp = DISAS_NORETURN; 1412 } 1413 1414 /* Generate #UD for the current instruction. The assumption here is that 1415 the instruction is known, but it isn't allowed in the current cpu mode. */ 1416 static void gen_illegal_opcode(DisasContext *s) 1417 { 1418 gen_exception(s, EXCP06_ILLOP); 1419 } 1420 1421 /* Generate #GP for the current instruction. */ 1422 static void gen_exception_gpf(DisasContext *s) 1423 { 1424 gen_exception(s, EXCP0D_GPF); 1425 } 1426 1427 /* Check for cpl == 0; if not, raise #GP and return false. */ 1428 static bool check_cpl0(DisasContext *s) 1429 { 1430 if (CPL(s) == 0) { 1431 return true; 1432 } 1433 gen_exception_gpf(s); 1434 return false; 1435 } 1436 1437 static void gen_shift_flags(DisasContext *s, MemOp ot, TCGv result, 1438 TCGv shm1, TCGv count, bool is_right) 1439 { 1440 TCGv_i32 z32, s32, oldop; 1441 TCGv z_tl; 1442 1443 /* Store the results into the CC variables. If we know that the 1444 variable must be dead, store unconditionally. Otherwise we'll 1445 need to not disrupt the current contents. */ 1446 z_tl = tcg_constant_tl(0); 1447 if (cc_op_live[s->cc_op] & USES_CC_DST) { 1448 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl, 1449 result, cpu_cc_dst); 1450 } else { 1451 tcg_gen_mov_tl(cpu_cc_dst, result); 1452 } 1453 if (cc_op_live[s->cc_op] & USES_CC_SRC) { 1454 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl, 1455 shm1, cpu_cc_src); 1456 } else { 1457 tcg_gen_mov_tl(cpu_cc_src, shm1); 1458 } 1459 1460 /* Get the two potential CC_OP values into temporaries. */ 1461 tcg_gen_movi_i32(s->tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot); 1462 if (s->cc_op == CC_OP_DYNAMIC) { 1463 oldop = cpu_cc_op; 1464 } else { 1465 tcg_gen_movi_i32(s->tmp3_i32, s->cc_op); 1466 oldop = s->tmp3_i32; 1467 } 1468 1469 /* Conditionally store the CC_OP value. */ 1470 z32 = tcg_constant_i32(0); 1471 s32 = tcg_temp_new_i32(); 1472 tcg_gen_trunc_tl_i32(s32, count); 1473 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, s->tmp2_i32, oldop); 1474 1475 /* The CC_OP value is no longer predictable. */ 1476 set_cc_op(s, CC_OP_DYNAMIC); 1477 } 1478 1479 /* XXX: add faster immediate case */ 1480 static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1, 1481 bool is_right, TCGv count_in) 1482 { 1483 target_ulong mask = (ot == MO_64 ? 63 : 31); 1484 TCGv count; 1485 1486 /* load */ 1487 if (op1 == OR_TMP0) { 1488 gen_op_ld_v(s, ot, s->T0, s->A0); 1489 } else { 1490 gen_op_mov_v_reg(s, ot, s->T0, op1); 1491 } 1492 1493 count = tcg_temp_new(); 1494 tcg_gen_andi_tl(count, count_in, mask); 1495 1496 switch (ot) { 1497 case MO_16: 1498 /* Note: we implement the Intel behaviour for shift count > 16. 1499 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A 1500 portion by constructing it as a 32-bit value. */ 1501 if (is_right) { 1502 tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16); 1503 tcg_gen_mov_tl(s->T1, s->T0); 1504 tcg_gen_mov_tl(s->T0, s->tmp0); 1505 } else { 1506 tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16); 1507 } 1508 /* 1509 * If TARGET_X86_64 defined then fall through into MO_32 case, 1510 * otherwise fall through default case. 1511 */ 1512 case MO_32: 1513 #ifdef TARGET_X86_64 1514 /* Concatenate the two 32-bit values and use a 64-bit shift. */ 1515 tcg_gen_subi_tl(s->tmp0, count, 1); 1516 if (is_right) { 1517 tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1); 1518 tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0); 1519 tcg_gen_shr_i64(s->T0, s->T0, count); 1520 } else { 1521 tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0); 1522 tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0); 1523 tcg_gen_shl_i64(s->T0, s->T0, count); 1524 tcg_gen_shri_i64(s->tmp0, s->tmp0, 32); 1525 tcg_gen_shri_i64(s->T0, s->T0, 32); 1526 } 1527 break; 1528 #endif 1529 default: 1530 tcg_gen_subi_tl(s->tmp0, count, 1); 1531 if (is_right) { 1532 tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0); 1533 1534 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1535 tcg_gen_shr_tl(s->T0, s->T0, count); 1536 tcg_gen_shl_tl(s->T1, s->T1, s->tmp4); 1537 } else { 1538 tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0); 1539 if (ot == MO_16) { 1540 /* Only needed if count > 16, for Intel behaviour. */ 1541 tcg_gen_subfi_tl(s->tmp4, 33, count); 1542 tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4); 1543 tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4); 1544 } 1545 1546 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1547 tcg_gen_shl_tl(s->T0, s->T0, count); 1548 tcg_gen_shr_tl(s->T1, s->T1, s->tmp4); 1549 } 1550 tcg_gen_movi_tl(s->tmp4, 0); 1551 tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4, 1552 s->tmp4, s->T1); 1553 tcg_gen_or_tl(s->T0, s->T0, s->T1); 1554 break; 1555 } 1556 1557 /* store */ 1558 gen_op_st_rm_T0_A0(s, ot, op1); 1559 1560 gen_shift_flags(s, ot, s->T0, s->tmp0, count, is_right); 1561 } 1562 1563 #define X86_MAX_INSN_LENGTH 15 1564 1565 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes) 1566 { 1567 uint64_t pc = s->pc; 1568 1569 /* This is a subsequent insn that crosses a page boundary. */ 1570 if (s->base.num_insns > 1 && 1571 !is_same_page(&s->base, s->pc + num_bytes - 1)) { 1572 siglongjmp(s->jmpbuf, 2); 1573 } 1574 1575 s->pc += num_bytes; 1576 if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) { 1577 /* If the instruction's 16th byte is on a different page than the 1st, a 1578 * page fault on the second page wins over the general protection fault 1579 * caused by the instruction being too long. 1580 * This can happen even if the operand is only one byte long! 1581 */ 1582 if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) { 1583 volatile uint8_t unused = 1584 cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK); 1585 (void) unused; 1586 } 1587 siglongjmp(s->jmpbuf, 1); 1588 } 1589 1590 return pc; 1591 } 1592 1593 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s) 1594 { 1595 return translator_ldub(env, &s->base, advance_pc(env, s, 1)); 1596 } 1597 1598 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s) 1599 { 1600 return translator_lduw(env, &s->base, advance_pc(env, s, 2)); 1601 } 1602 1603 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s) 1604 { 1605 return translator_ldl(env, &s->base, advance_pc(env, s, 4)); 1606 } 1607 1608 #ifdef TARGET_X86_64 1609 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s) 1610 { 1611 return translator_ldq(env, &s->base, advance_pc(env, s, 8)); 1612 } 1613 #endif 1614 1615 /* Decompose an address. */ 1616 1617 typedef struct AddressParts { 1618 int def_seg; 1619 int base; 1620 int index; 1621 int scale; 1622 target_long disp; 1623 } AddressParts; 1624 1625 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s, 1626 int modrm) 1627 { 1628 int def_seg, base, index, scale, mod, rm; 1629 target_long disp; 1630 bool havesib; 1631 1632 def_seg = R_DS; 1633 index = -1; 1634 scale = 0; 1635 disp = 0; 1636 1637 mod = (modrm >> 6) & 3; 1638 rm = modrm & 7; 1639 base = rm | REX_B(s); 1640 1641 if (mod == 3) { 1642 /* Normally filtered out earlier, but including this path 1643 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */ 1644 goto done; 1645 } 1646 1647 switch (s->aflag) { 1648 case MO_64: 1649 case MO_32: 1650 havesib = 0; 1651 if (rm == 4) { 1652 int code = x86_ldub_code(env, s); 1653 scale = (code >> 6) & 3; 1654 index = ((code >> 3) & 7) | REX_X(s); 1655 if (index == 4) { 1656 index = -1; /* no index */ 1657 } 1658 base = (code & 7) | REX_B(s); 1659 havesib = 1; 1660 } 1661 1662 switch (mod) { 1663 case 0: 1664 if ((base & 7) == 5) { 1665 base = -1; 1666 disp = (int32_t)x86_ldl_code(env, s); 1667 if (CODE64(s) && !havesib) { 1668 base = -2; 1669 disp += s->pc + s->rip_offset; 1670 } 1671 } 1672 break; 1673 case 1: 1674 disp = (int8_t)x86_ldub_code(env, s); 1675 break; 1676 default: 1677 case 2: 1678 disp = (int32_t)x86_ldl_code(env, s); 1679 break; 1680 } 1681 1682 /* For correct popl handling with esp. */ 1683 if (base == R_ESP && s->popl_esp_hack) { 1684 disp += s->popl_esp_hack; 1685 } 1686 if (base == R_EBP || base == R_ESP) { 1687 def_seg = R_SS; 1688 } 1689 break; 1690 1691 case MO_16: 1692 if (mod == 0) { 1693 if (rm == 6) { 1694 base = -1; 1695 disp = x86_lduw_code(env, s); 1696 break; 1697 } 1698 } else if (mod == 1) { 1699 disp = (int8_t)x86_ldub_code(env, s); 1700 } else { 1701 disp = (int16_t)x86_lduw_code(env, s); 1702 } 1703 1704 switch (rm) { 1705 case 0: 1706 base = R_EBX; 1707 index = R_ESI; 1708 break; 1709 case 1: 1710 base = R_EBX; 1711 index = R_EDI; 1712 break; 1713 case 2: 1714 base = R_EBP; 1715 index = R_ESI; 1716 def_seg = R_SS; 1717 break; 1718 case 3: 1719 base = R_EBP; 1720 index = R_EDI; 1721 def_seg = R_SS; 1722 break; 1723 case 4: 1724 base = R_ESI; 1725 break; 1726 case 5: 1727 base = R_EDI; 1728 break; 1729 case 6: 1730 base = R_EBP; 1731 def_seg = R_SS; 1732 break; 1733 default: 1734 case 7: 1735 base = R_EBX; 1736 break; 1737 } 1738 break; 1739 1740 default: 1741 g_assert_not_reached(); 1742 } 1743 1744 done: 1745 return (AddressParts){ def_seg, base, index, scale, disp }; 1746 } 1747 1748 /* Compute the address, with a minimum number of TCG ops. */ 1749 static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib) 1750 { 1751 TCGv ea = NULL; 1752 1753 if (a.index >= 0 && !is_vsib) { 1754 if (a.scale == 0) { 1755 ea = cpu_regs[a.index]; 1756 } else { 1757 tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale); 1758 ea = s->A0; 1759 } 1760 if (a.base >= 0) { 1761 tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]); 1762 ea = s->A0; 1763 } 1764 } else if (a.base >= 0) { 1765 ea = cpu_regs[a.base]; 1766 } 1767 if (!ea) { 1768 if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) { 1769 /* With cpu_eip ~= pc_save, the expression is pc-relative. */ 1770 tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save); 1771 } else { 1772 tcg_gen_movi_tl(s->A0, a.disp); 1773 } 1774 ea = s->A0; 1775 } else if (a.disp != 0) { 1776 tcg_gen_addi_tl(s->A0, ea, a.disp); 1777 ea = s->A0; 1778 } 1779 1780 return ea; 1781 } 1782 1783 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) 1784 { 1785 AddressParts a = gen_lea_modrm_0(env, s, modrm); 1786 TCGv ea = gen_lea_modrm_1(s, a, false); 1787 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override); 1788 } 1789 1790 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm) 1791 { 1792 (void)gen_lea_modrm_0(env, s, modrm); 1793 } 1794 1795 /* Used for BNDCL, BNDCU, BNDCN. */ 1796 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm, 1797 TCGCond cond, TCGv_i64 bndv) 1798 { 1799 AddressParts a = gen_lea_modrm_0(env, s, modrm); 1800 TCGv ea = gen_lea_modrm_1(s, a, false); 1801 1802 tcg_gen_extu_tl_i64(s->tmp1_i64, ea); 1803 if (!CODE64(s)) { 1804 tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64); 1805 } 1806 tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv); 1807 tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64); 1808 gen_helper_bndck(tcg_env, s->tmp2_i32); 1809 } 1810 1811 /* used for LEA and MOV AX, mem */ 1812 static void gen_add_A0_ds_seg(DisasContext *s) 1813 { 1814 gen_lea_v_seg(s, s->aflag, s->A0, R_DS, s->override); 1815 } 1816 1817 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg == 1818 OR_TMP0 */ 1819 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm, 1820 MemOp ot, int reg, int is_store) 1821 { 1822 int mod, rm; 1823 1824 mod = (modrm >> 6) & 3; 1825 rm = (modrm & 7) | REX_B(s); 1826 if (mod == 3) { 1827 if (is_store) { 1828 if (reg != OR_TMP0) 1829 gen_op_mov_v_reg(s, ot, s->T0, reg); 1830 gen_op_mov_reg_v(s, ot, rm, s->T0); 1831 } else { 1832 gen_op_mov_v_reg(s, ot, s->T0, rm); 1833 if (reg != OR_TMP0) 1834 gen_op_mov_reg_v(s, ot, reg, s->T0); 1835 } 1836 } else { 1837 gen_lea_modrm(env, s, modrm); 1838 if (is_store) { 1839 if (reg != OR_TMP0) 1840 gen_op_mov_v_reg(s, ot, s->T0, reg); 1841 gen_op_st_v(s, ot, s->T0, s->A0); 1842 } else { 1843 gen_op_ld_v(s, ot, s->T0, s->A0); 1844 if (reg != OR_TMP0) 1845 gen_op_mov_reg_v(s, ot, reg, s->T0); 1846 } 1847 } 1848 } 1849 1850 static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot) 1851 { 1852 target_ulong ret; 1853 1854 switch (ot) { 1855 case MO_8: 1856 ret = x86_ldub_code(env, s); 1857 break; 1858 case MO_16: 1859 ret = x86_lduw_code(env, s); 1860 break; 1861 case MO_32: 1862 ret = x86_ldl_code(env, s); 1863 break; 1864 #ifdef TARGET_X86_64 1865 case MO_64: 1866 ret = x86_ldq_code(env, s); 1867 break; 1868 #endif 1869 default: 1870 g_assert_not_reached(); 1871 } 1872 return ret; 1873 } 1874 1875 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot) 1876 { 1877 uint32_t ret; 1878 1879 switch (ot) { 1880 case MO_8: 1881 ret = x86_ldub_code(env, s); 1882 break; 1883 case MO_16: 1884 ret = x86_lduw_code(env, s); 1885 break; 1886 case MO_32: 1887 #ifdef TARGET_X86_64 1888 case MO_64: 1889 #endif 1890 ret = x86_ldl_code(env, s); 1891 break; 1892 default: 1893 g_assert_not_reached(); 1894 } 1895 return ret; 1896 } 1897 1898 static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot) 1899 { 1900 target_long ret; 1901 1902 switch (ot) { 1903 case MO_8: 1904 ret = (int8_t) x86_ldub_code(env, s); 1905 break; 1906 case MO_16: 1907 ret = (int16_t) x86_lduw_code(env, s); 1908 break; 1909 case MO_32: 1910 ret = (int32_t) x86_ldl_code(env, s); 1911 break; 1912 #ifdef TARGET_X86_64 1913 case MO_64: 1914 ret = x86_ldq_code(env, s); 1915 break; 1916 #endif 1917 default: 1918 g_assert_not_reached(); 1919 } 1920 return ret; 1921 } 1922 1923 static void gen_conditional_jump_labels(DisasContext *s, target_long diff, 1924 TCGLabel *not_taken, TCGLabel *taken) 1925 { 1926 if (not_taken) { 1927 gen_set_label(not_taken); 1928 } 1929 gen_jmp_rel_csize(s, 0, 1); 1930 1931 gen_set_label(taken); 1932 gen_jmp_rel(s, s->dflag, diff, 0); 1933 } 1934 1935 static void gen_jcc(DisasContext *s, int b, int diff) 1936 { 1937 TCGLabel *l1 = gen_new_label(); 1938 1939 gen_jcc1(s, b, l1); 1940 gen_conditional_jump_labels(s, diff, NULL, l1); 1941 } 1942 1943 static void gen_cmovcc1(DisasContext *s, int b, TCGv dest, TCGv src) 1944 { 1945 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1946 1947 if (!cc.use_reg2) { 1948 cc.reg2 = tcg_constant_tl(cc.imm); 1949 } 1950 1951 tcg_gen_movcond_tl(cc.cond, dest, cc.reg, cc.reg2, src, dest); 1952 } 1953 1954 static void gen_op_movl_seg_real(DisasContext *s, X86Seg seg_reg, TCGv seg) 1955 { 1956 TCGv selector = tcg_temp_new(); 1957 tcg_gen_ext16u_tl(selector, seg); 1958 tcg_gen_st32_tl(selector, tcg_env, 1959 offsetof(CPUX86State,segs[seg_reg].selector)); 1960 tcg_gen_shli_tl(cpu_seg_base[seg_reg], selector, 4); 1961 } 1962 1963 /* move SRC to seg_reg and compute if the CPU state may change. Never 1964 call this function with seg_reg == R_CS */ 1965 static void gen_movl_seg(DisasContext *s, X86Seg seg_reg, TCGv src) 1966 { 1967 if (PE(s) && !VM86(s)) { 1968 tcg_gen_trunc_tl_i32(s->tmp2_i32, src); 1969 gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32); 1970 /* abort translation because the addseg value may change or 1971 because ss32 may change. For R_SS, translation must always 1972 stop as a special handling must be done to disable hardware 1973 interrupts for the next instruction */ 1974 if (seg_reg == R_SS) { 1975 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 1976 } else if (CODE32(s) && seg_reg < R_FS) { 1977 s->base.is_jmp = DISAS_EOB_NEXT; 1978 } 1979 } else { 1980 gen_op_movl_seg_real(s, seg_reg, src); 1981 if (seg_reg == R_SS) { 1982 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 1983 } 1984 } 1985 } 1986 1987 static void gen_far_call(DisasContext *s) 1988 { 1989 TCGv_i32 new_cs = tcg_temp_new_i32(); 1990 tcg_gen_trunc_tl_i32(new_cs, s->T1); 1991 if (PE(s) && !VM86(s)) { 1992 gen_helper_lcall_protected(tcg_env, new_cs, s->T0, 1993 tcg_constant_i32(s->dflag - 1), 1994 eip_next_tl(s)); 1995 } else { 1996 TCGv_i32 new_eip = tcg_temp_new_i32(); 1997 tcg_gen_trunc_tl_i32(new_eip, s->T0); 1998 gen_helper_lcall_real(tcg_env, new_cs, new_eip, 1999 tcg_constant_i32(s->dflag - 1), 2000 eip_next_i32(s)); 2001 } 2002 s->base.is_jmp = DISAS_JUMP; 2003 } 2004 2005 static void gen_far_jmp(DisasContext *s) 2006 { 2007 if (PE(s) && !VM86(s)) { 2008 TCGv_i32 new_cs = tcg_temp_new_i32(); 2009 tcg_gen_trunc_tl_i32(new_cs, s->T1); 2010 gen_helper_ljmp_protected(tcg_env, new_cs, s->T0, 2011 eip_next_tl(s)); 2012 } else { 2013 gen_op_movl_seg_real(s, R_CS, s->T1); 2014 gen_op_jmp_v(s, s->T0); 2015 } 2016 s->base.is_jmp = DISAS_JUMP; 2017 } 2018 2019 static void gen_svm_check_intercept(DisasContext *s, uint32_t type) 2020 { 2021 /* no SVM activated; fast case */ 2022 if (likely(!GUEST(s))) { 2023 return; 2024 } 2025 gen_helper_svm_check_intercept(tcg_env, tcg_constant_i32(type)); 2026 } 2027 2028 static inline void gen_stack_update(DisasContext *s, int addend) 2029 { 2030 gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend); 2031 } 2032 2033 /* Generate a push. It depends on ss32, addseg and dflag. */ 2034 static void gen_push_v(DisasContext *s, TCGv val) 2035 { 2036 MemOp d_ot = mo_pushpop(s, s->dflag); 2037 MemOp a_ot = mo_stacksize(s); 2038 int size = 1 << d_ot; 2039 TCGv new_esp = s->A0; 2040 2041 tcg_gen_subi_tl(s->A0, cpu_regs[R_ESP], size); 2042 2043 if (!CODE64(s)) { 2044 if (ADDSEG(s)) { 2045 new_esp = tcg_temp_new(); 2046 tcg_gen_mov_tl(new_esp, s->A0); 2047 } 2048 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2049 } 2050 2051 gen_op_st_v(s, d_ot, val, s->A0); 2052 gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp); 2053 } 2054 2055 /* two step pop is necessary for precise exceptions */ 2056 static MemOp gen_pop_T0(DisasContext *s) 2057 { 2058 MemOp d_ot = mo_pushpop(s, s->dflag); 2059 2060 gen_lea_v_seg_dest(s, mo_stacksize(s), s->T0, cpu_regs[R_ESP], R_SS, -1); 2061 gen_op_ld_v(s, d_ot, s->T0, s->T0); 2062 2063 return d_ot; 2064 } 2065 2066 static inline void gen_pop_update(DisasContext *s, MemOp ot) 2067 { 2068 gen_stack_update(s, 1 << ot); 2069 } 2070 2071 static inline void gen_stack_A0(DisasContext *s) 2072 { 2073 gen_lea_v_seg(s, SS32(s) ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1); 2074 } 2075 2076 static void gen_pusha(DisasContext *s) 2077 { 2078 MemOp s_ot = SS32(s) ? MO_32 : MO_16; 2079 MemOp d_ot = s->dflag; 2080 int size = 1 << d_ot; 2081 int i; 2082 2083 for (i = 0; i < 8; i++) { 2084 tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], (i - 8) * size); 2085 gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1); 2086 gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0); 2087 } 2088 2089 gen_stack_update(s, -8 * size); 2090 } 2091 2092 static void gen_popa(DisasContext *s) 2093 { 2094 MemOp s_ot = SS32(s) ? MO_32 : MO_16; 2095 MemOp d_ot = s->dflag; 2096 int size = 1 << d_ot; 2097 int i; 2098 2099 for (i = 0; i < 8; i++) { 2100 /* ESP is not reloaded */ 2101 if (7 - i == R_ESP) { 2102 continue; 2103 } 2104 tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], i * size); 2105 gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1); 2106 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2107 gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0); 2108 } 2109 2110 gen_stack_update(s, 8 * size); 2111 } 2112 2113 static void gen_enter(DisasContext *s, int esp_addend, int level) 2114 { 2115 MemOp d_ot = mo_pushpop(s, s->dflag); 2116 MemOp a_ot = CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16; 2117 int size = 1 << d_ot; 2118 2119 /* Push BP; compute FrameTemp into T1. */ 2120 tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size); 2121 gen_lea_v_seg(s, a_ot, s->T1, R_SS, -1); 2122 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0); 2123 2124 level &= 31; 2125 if (level != 0) { 2126 int i; 2127 2128 /* Copy level-1 pointers from the previous frame. */ 2129 for (i = 1; i < level; ++i) { 2130 tcg_gen_subi_tl(s->A0, cpu_regs[R_EBP], size * i); 2131 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2132 gen_op_ld_v(s, d_ot, s->tmp0, s->A0); 2133 2134 tcg_gen_subi_tl(s->A0, s->T1, size * i); 2135 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2136 gen_op_st_v(s, d_ot, s->tmp0, s->A0); 2137 } 2138 2139 /* Push the current FrameTemp as the last level. */ 2140 tcg_gen_subi_tl(s->A0, s->T1, size * level); 2141 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2142 gen_op_st_v(s, d_ot, s->T1, s->A0); 2143 } 2144 2145 /* Copy the FrameTemp value to EBP. */ 2146 gen_op_mov_reg_v(s, a_ot, R_EBP, s->T1); 2147 2148 /* Compute the final value of ESP. */ 2149 tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level); 2150 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2151 } 2152 2153 static void gen_leave(DisasContext *s) 2154 { 2155 MemOp d_ot = mo_pushpop(s, s->dflag); 2156 MemOp a_ot = mo_stacksize(s); 2157 2158 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1); 2159 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2160 2161 tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot); 2162 2163 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0); 2164 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2165 } 2166 2167 /* Similarly, except that the assumption here is that we don't decode 2168 the instruction at all -- either a missing opcode, an unimplemented 2169 feature, or just a bogus instruction stream. */ 2170 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) 2171 { 2172 gen_illegal_opcode(s); 2173 2174 if (qemu_loglevel_mask(LOG_UNIMP)) { 2175 FILE *logfile = qemu_log_trylock(); 2176 if (logfile) { 2177 target_ulong pc = s->base.pc_next, end = s->pc; 2178 2179 fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc); 2180 for (; pc < end; ++pc) { 2181 fprintf(logfile, " %02x", cpu_ldub_code(env, pc)); 2182 } 2183 fprintf(logfile, "\n"); 2184 qemu_log_unlock(logfile); 2185 } 2186 } 2187 } 2188 2189 /* an interrupt is different from an exception because of the 2190 privilege checks */ 2191 static void gen_interrupt(DisasContext *s, uint8_t intno) 2192 { 2193 gen_update_cc_op(s); 2194 gen_update_eip_cur(s); 2195 gen_helper_raise_interrupt(tcg_env, tcg_constant_i32(intno), 2196 cur_insn_len_i32(s)); 2197 s->base.is_jmp = DISAS_NORETURN; 2198 } 2199 2200 static void gen_set_hflag(DisasContext *s, uint32_t mask) 2201 { 2202 if ((s->flags & mask) == 0) { 2203 TCGv_i32 t = tcg_temp_new_i32(); 2204 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2205 tcg_gen_ori_i32(t, t, mask); 2206 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2207 s->flags |= mask; 2208 } 2209 } 2210 2211 static void gen_reset_hflag(DisasContext *s, uint32_t mask) 2212 { 2213 if (s->flags & mask) { 2214 TCGv_i32 t = tcg_temp_new_i32(); 2215 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2216 tcg_gen_andi_i32(t, t, ~mask); 2217 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2218 s->flags &= ~mask; 2219 } 2220 } 2221 2222 static void gen_set_eflags(DisasContext *s, target_ulong mask) 2223 { 2224 TCGv t = tcg_temp_new(); 2225 2226 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2227 tcg_gen_ori_tl(t, t, mask); 2228 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2229 } 2230 2231 static void gen_reset_eflags(DisasContext *s, target_ulong mask) 2232 { 2233 TCGv t = tcg_temp_new(); 2234 2235 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2236 tcg_gen_andi_tl(t, t, ~mask); 2237 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2238 } 2239 2240 /* Clear BND registers during legacy branches. */ 2241 static void gen_bnd_jmp(DisasContext *s) 2242 { 2243 /* Clear the registers only if BND prefix is missing, MPX is enabled, 2244 and if the BNDREGs are known to be in use (non-zero) already. 2245 The helper itself will check BNDPRESERVE at runtime. */ 2246 if ((s->prefix & PREFIX_REPNZ) == 0 2247 && (s->flags & HF_MPX_EN_MASK) != 0 2248 && (s->flags & HF_MPX_IU_MASK) != 0) { 2249 gen_helper_bnd_jmp(tcg_env); 2250 } 2251 } 2252 2253 /* Generate an end of block. Trace exception is also generated if needed. 2254 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. 2255 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of 2256 S->TF. This is used by the syscall/sysret insns. */ 2257 static void 2258 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr) 2259 { 2260 bool inhibit_reset; 2261 2262 gen_update_cc_op(s); 2263 2264 /* If several instructions disable interrupts, only the first does it. */ 2265 inhibit_reset = false; 2266 if (s->flags & HF_INHIBIT_IRQ_MASK) { 2267 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); 2268 inhibit_reset = true; 2269 } else if (inhibit) { 2270 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); 2271 } 2272 2273 if (s->base.tb->flags & HF_RF_MASK) { 2274 gen_reset_eflags(s, RF_MASK); 2275 } 2276 if (recheck_tf) { 2277 gen_helper_rechecking_single_step(tcg_env); 2278 tcg_gen_exit_tb(NULL, 0); 2279 } else if (s->flags & HF_TF_MASK) { 2280 gen_helper_single_step(tcg_env); 2281 } else if (jr && 2282 /* give irqs a chance to happen */ 2283 !inhibit_reset) { 2284 tcg_gen_lookup_and_goto_ptr(); 2285 } else { 2286 tcg_gen_exit_tb(NULL, 0); 2287 } 2288 s->base.is_jmp = DISAS_NORETURN; 2289 } 2290 2291 static inline void 2292 gen_eob_syscall(DisasContext *s) 2293 { 2294 gen_eob_worker(s, false, true, false); 2295 } 2296 2297 /* End of block. Set HF_INHIBIT_IRQ_MASK if it isn't already set. */ 2298 static void gen_eob_inhibit_irq(DisasContext *s) 2299 { 2300 gen_eob_worker(s, true, false, false); 2301 } 2302 2303 /* End of block, resetting the inhibit irq flag. */ 2304 static void gen_eob(DisasContext *s) 2305 { 2306 gen_eob_worker(s, false, false, false); 2307 } 2308 2309 /* Jump to register */ 2310 static void gen_jr(DisasContext *s) 2311 { 2312 gen_eob_worker(s, false, false, true); 2313 } 2314 2315 /* Jump to eip+diff, truncating the result to OT. */ 2316 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num) 2317 { 2318 bool use_goto_tb = s->jmp_opt; 2319 target_ulong mask = -1; 2320 target_ulong new_pc = s->pc + diff; 2321 target_ulong new_eip = new_pc - s->cs_base; 2322 2323 assert(!s->cc_op_dirty); 2324 2325 /* In 64-bit mode, operand size is fixed at 64 bits. */ 2326 if (!CODE64(s)) { 2327 if (ot == MO_16) { 2328 mask = 0xffff; 2329 if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) { 2330 use_goto_tb = false; 2331 } 2332 } else { 2333 mask = 0xffffffff; 2334 } 2335 } 2336 new_eip &= mask; 2337 2338 if (tb_cflags(s->base.tb) & CF_PCREL) { 2339 tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save); 2340 /* 2341 * If we can prove the branch does not leave the page and we have 2342 * no extra masking to apply (data16 branch in code32, see above), 2343 * then we have also proven that the addition does not wrap. 2344 */ 2345 if (!use_goto_tb || !is_same_page(&s->base, new_pc)) { 2346 tcg_gen_andi_tl(cpu_eip, cpu_eip, mask); 2347 use_goto_tb = false; 2348 } 2349 } else if (!CODE64(s)) { 2350 new_pc = (uint32_t)(new_eip + s->cs_base); 2351 } 2352 2353 if (use_goto_tb && translator_use_goto_tb(&s->base, new_pc)) { 2354 /* jump to same page: we can use a direct jump */ 2355 tcg_gen_goto_tb(tb_num); 2356 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2357 tcg_gen_movi_tl(cpu_eip, new_eip); 2358 } 2359 tcg_gen_exit_tb(s->base.tb, tb_num); 2360 s->base.is_jmp = DISAS_NORETURN; 2361 } else { 2362 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2363 tcg_gen_movi_tl(cpu_eip, new_eip); 2364 } 2365 if (s->jmp_opt) { 2366 gen_jr(s); /* jump to another page */ 2367 } else { 2368 gen_eob(s); /* exit to main loop */ 2369 } 2370 } 2371 } 2372 2373 /* Jump to eip+diff, truncating to the current code size. */ 2374 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num) 2375 { 2376 /* CODE64 ignores the OT argument, so we need not consider it. */ 2377 gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num); 2378 } 2379 2380 static inline void gen_ldq_env_A0(DisasContext *s, int offset) 2381 { 2382 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2383 tcg_gen_st_i64(s->tmp1_i64, tcg_env, offset); 2384 } 2385 2386 static inline void gen_stq_env_A0(DisasContext *s, int offset) 2387 { 2388 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, offset); 2389 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2390 } 2391 2392 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align) 2393 { 2394 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2395 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2396 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2397 int mem_index = s->mem_index; 2398 TCGv_i128 t = tcg_temp_new_i128(); 2399 2400 tcg_gen_qemu_ld_i128(t, s->A0, mem_index, mop); 2401 tcg_gen_st_i128(t, tcg_env, offset); 2402 } 2403 2404 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align) 2405 { 2406 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2407 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2408 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2409 int mem_index = s->mem_index; 2410 TCGv_i128 t = tcg_temp_new_i128(); 2411 2412 tcg_gen_ld_i128(t, tcg_env, offset); 2413 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop); 2414 } 2415 2416 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align) 2417 { 2418 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2419 int mem_index = s->mem_index; 2420 TCGv_i128 t0 = tcg_temp_new_i128(); 2421 TCGv_i128 t1 = tcg_temp_new_i128(); 2422 2423 tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2424 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2425 tcg_gen_qemu_ld_i128(t1, s->tmp0, mem_index, mop); 2426 2427 tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2428 tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2429 } 2430 2431 static void gen_sty_env_A0(DisasContext *s, int offset, bool align) 2432 { 2433 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2434 int mem_index = s->mem_index; 2435 TCGv_i128 t = tcg_temp_new_i128(); 2436 2437 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2438 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2439 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2440 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2441 tcg_gen_qemu_st_i128(t, s->tmp0, mem_index, mop); 2442 } 2443 2444 static void gen_cmpxchg8b(DisasContext *s, CPUX86State *env, int modrm) 2445 { 2446 TCGv_i64 cmp, val, old; 2447 TCGv Z; 2448 2449 gen_lea_modrm(env, s, modrm); 2450 2451 cmp = tcg_temp_new_i64(); 2452 val = tcg_temp_new_i64(); 2453 old = tcg_temp_new_i64(); 2454 2455 /* Construct the comparison values from the register pair. */ 2456 tcg_gen_concat_tl_i64(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]); 2457 tcg_gen_concat_tl_i64(val, cpu_regs[R_EBX], cpu_regs[R_ECX]); 2458 2459 /* Only require atomic with LOCK; non-parallel handled in generator. */ 2460 if (s->prefix & PREFIX_LOCK) { 2461 tcg_gen_atomic_cmpxchg_i64(old, s->A0, cmp, val, s->mem_index, MO_TEUQ); 2462 } else { 2463 tcg_gen_nonatomic_cmpxchg_i64(old, s->A0, cmp, val, 2464 s->mem_index, MO_TEUQ); 2465 } 2466 2467 /* Set tmp0 to match the required value of Z. */ 2468 tcg_gen_setcond_i64(TCG_COND_EQ, cmp, old, cmp); 2469 Z = tcg_temp_new(); 2470 tcg_gen_trunc_i64_tl(Z, cmp); 2471 2472 /* 2473 * Extract the result values for the register pair. 2474 * For 32-bit, we may do this unconditionally, because on success (Z=1), 2475 * the old value matches the previous value in EDX:EAX. For x86_64, 2476 * the store must be conditional, because we must leave the source 2477 * registers unchanged on success, and zero-extend the writeback 2478 * on failure (Z=0). 2479 */ 2480 if (TARGET_LONG_BITS == 32) { 2481 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], old); 2482 } else { 2483 TCGv zero = tcg_constant_tl(0); 2484 2485 tcg_gen_extr_i64_tl(s->T0, s->T1, old); 2486 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EAX], Z, zero, 2487 s->T0, cpu_regs[R_EAX]); 2488 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EDX], Z, zero, 2489 s->T1, cpu_regs[R_EDX]); 2490 } 2491 2492 /* Update Z. */ 2493 gen_compute_eflags(s); 2494 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, Z, ctz32(CC_Z), 1); 2495 } 2496 2497 #ifdef TARGET_X86_64 2498 static void gen_cmpxchg16b(DisasContext *s, CPUX86State *env, int modrm) 2499 { 2500 MemOp mop = MO_TE | MO_128 | MO_ALIGN; 2501 TCGv_i64 t0, t1; 2502 TCGv_i128 cmp, val; 2503 2504 gen_lea_modrm(env, s, modrm); 2505 2506 cmp = tcg_temp_new_i128(); 2507 val = tcg_temp_new_i128(); 2508 tcg_gen_concat_i64_i128(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]); 2509 tcg_gen_concat_i64_i128(val, cpu_regs[R_EBX], cpu_regs[R_ECX]); 2510 2511 /* Only require atomic with LOCK; non-parallel handled in generator. */ 2512 if (s->prefix & PREFIX_LOCK) { 2513 tcg_gen_atomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop); 2514 } else { 2515 tcg_gen_nonatomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop); 2516 } 2517 2518 tcg_gen_extr_i128_i64(s->T0, s->T1, val); 2519 2520 /* Determine success after the fact. */ 2521 t0 = tcg_temp_new_i64(); 2522 t1 = tcg_temp_new_i64(); 2523 tcg_gen_xor_i64(t0, s->T0, cpu_regs[R_EAX]); 2524 tcg_gen_xor_i64(t1, s->T1, cpu_regs[R_EDX]); 2525 tcg_gen_or_i64(t0, t0, t1); 2526 2527 /* Update Z. */ 2528 gen_compute_eflags(s); 2529 tcg_gen_setcondi_i64(TCG_COND_EQ, t0, t0, 0); 2530 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, t0, ctz32(CC_Z), 1); 2531 2532 /* 2533 * Extract the result values for the register pair. We may do this 2534 * unconditionally, because on success (Z=1), the old value matches 2535 * the previous value in RDX:RAX. 2536 */ 2537 tcg_gen_mov_i64(cpu_regs[R_EAX], s->T0); 2538 tcg_gen_mov_i64(cpu_regs[R_EDX], s->T1); 2539 } 2540 #endif 2541 2542 static bool disas_insn_x87(DisasContext *s, CPUState *cpu, int b) 2543 { 2544 CPUX86State *env = cpu_env(cpu); 2545 bool update_fip = true; 2546 int modrm, mod, rm, op; 2547 2548 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 2549 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 2550 /* XXX: what to do if illegal op ? */ 2551 gen_exception(s, EXCP07_PREX); 2552 return true; 2553 } 2554 modrm = x86_ldub_code(env, s); 2555 mod = (modrm >> 6) & 3; 2556 rm = modrm & 7; 2557 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 2558 if (mod != 3) { 2559 /* memory op */ 2560 AddressParts a = gen_lea_modrm_0(env, s, modrm); 2561 TCGv ea = gen_lea_modrm_1(s, a, false); 2562 TCGv last_addr = tcg_temp_new(); 2563 bool update_fdp = true; 2564 2565 tcg_gen_mov_tl(last_addr, ea); 2566 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override); 2567 2568 switch (op) { 2569 case 0x00 ... 0x07: /* fxxxs */ 2570 case 0x10 ... 0x17: /* fixxxl */ 2571 case 0x20 ... 0x27: /* fxxxl */ 2572 case 0x30 ... 0x37: /* fixxx */ 2573 { 2574 int op1; 2575 op1 = op & 7; 2576 2577 switch (op >> 4) { 2578 case 0: 2579 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2580 s->mem_index, MO_LEUL); 2581 gen_helper_flds_FT0(tcg_env, s->tmp2_i32); 2582 break; 2583 case 1: 2584 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2585 s->mem_index, MO_LEUL); 2586 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2587 break; 2588 case 2: 2589 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2590 s->mem_index, MO_LEUQ); 2591 gen_helper_fldl_FT0(tcg_env, s->tmp1_i64); 2592 break; 2593 case 3: 2594 default: 2595 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2596 s->mem_index, MO_LESW); 2597 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2598 break; 2599 } 2600 2601 gen_helper_fp_arith_ST0_FT0(op1); 2602 if (op1 == 3) { 2603 /* fcomp needs pop */ 2604 gen_helper_fpop(tcg_env); 2605 } 2606 } 2607 break; 2608 case 0x08: /* flds */ 2609 case 0x0a: /* fsts */ 2610 case 0x0b: /* fstps */ 2611 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 2612 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 2613 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 2614 switch (op & 7) { 2615 case 0: 2616 switch (op >> 4) { 2617 case 0: 2618 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2619 s->mem_index, MO_LEUL); 2620 gen_helper_flds_ST0(tcg_env, s->tmp2_i32); 2621 break; 2622 case 1: 2623 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2624 s->mem_index, MO_LEUL); 2625 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2626 break; 2627 case 2: 2628 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2629 s->mem_index, MO_LEUQ); 2630 gen_helper_fldl_ST0(tcg_env, s->tmp1_i64); 2631 break; 2632 case 3: 2633 default: 2634 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2635 s->mem_index, MO_LESW); 2636 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2637 break; 2638 } 2639 break; 2640 case 1: 2641 /* XXX: the corresponding CPUID bit must be tested ! */ 2642 switch (op >> 4) { 2643 case 1: 2644 gen_helper_fisttl_ST0(s->tmp2_i32, tcg_env); 2645 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2646 s->mem_index, MO_LEUL); 2647 break; 2648 case 2: 2649 gen_helper_fisttll_ST0(s->tmp1_i64, tcg_env); 2650 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2651 s->mem_index, MO_LEUQ); 2652 break; 2653 case 3: 2654 default: 2655 gen_helper_fistt_ST0(s->tmp2_i32, tcg_env); 2656 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2657 s->mem_index, MO_LEUW); 2658 break; 2659 } 2660 gen_helper_fpop(tcg_env); 2661 break; 2662 default: 2663 switch (op >> 4) { 2664 case 0: 2665 gen_helper_fsts_ST0(s->tmp2_i32, tcg_env); 2666 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2667 s->mem_index, MO_LEUL); 2668 break; 2669 case 1: 2670 gen_helper_fistl_ST0(s->tmp2_i32, tcg_env); 2671 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2672 s->mem_index, MO_LEUL); 2673 break; 2674 case 2: 2675 gen_helper_fstl_ST0(s->tmp1_i64, tcg_env); 2676 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2677 s->mem_index, MO_LEUQ); 2678 break; 2679 case 3: 2680 default: 2681 gen_helper_fist_ST0(s->tmp2_i32, tcg_env); 2682 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2683 s->mem_index, MO_LEUW); 2684 break; 2685 } 2686 if ((op & 7) == 3) { 2687 gen_helper_fpop(tcg_env); 2688 } 2689 break; 2690 } 2691 break; 2692 case 0x0c: /* fldenv mem */ 2693 gen_helper_fldenv(tcg_env, s->A0, 2694 tcg_constant_i32(s->dflag - 1)); 2695 update_fip = update_fdp = false; 2696 break; 2697 case 0x0d: /* fldcw mem */ 2698 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2699 s->mem_index, MO_LEUW); 2700 gen_helper_fldcw(tcg_env, s->tmp2_i32); 2701 update_fip = update_fdp = false; 2702 break; 2703 case 0x0e: /* fnstenv mem */ 2704 gen_helper_fstenv(tcg_env, s->A0, 2705 tcg_constant_i32(s->dflag - 1)); 2706 update_fip = update_fdp = false; 2707 break; 2708 case 0x0f: /* fnstcw mem */ 2709 gen_helper_fnstcw(s->tmp2_i32, tcg_env); 2710 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2711 s->mem_index, MO_LEUW); 2712 update_fip = update_fdp = false; 2713 break; 2714 case 0x1d: /* fldt mem */ 2715 gen_helper_fldt_ST0(tcg_env, s->A0); 2716 break; 2717 case 0x1f: /* fstpt mem */ 2718 gen_helper_fstt_ST0(tcg_env, s->A0); 2719 gen_helper_fpop(tcg_env); 2720 break; 2721 case 0x2c: /* frstor mem */ 2722 gen_helper_frstor(tcg_env, s->A0, 2723 tcg_constant_i32(s->dflag - 1)); 2724 update_fip = update_fdp = false; 2725 break; 2726 case 0x2e: /* fnsave mem */ 2727 gen_helper_fsave(tcg_env, s->A0, 2728 tcg_constant_i32(s->dflag - 1)); 2729 update_fip = update_fdp = false; 2730 break; 2731 case 0x2f: /* fnstsw mem */ 2732 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2733 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2734 s->mem_index, MO_LEUW); 2735 update_fip = update_fdp = false; 2736 break; 2737 case 0x3c: /* fbld */ 2738 gen_helper_fbld_ST0(tcg_env, s->A0); 2739 break; 2740 case 0x3e: /* fbstp */ 2741 gen_helper_fbst_ST0(tcg_env, s->A0); 2742 gen_helper_fpop(tcg_env); 2743 break; 2744 case 0x3d: /* fildll */ 2745 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2746 s->mem_index, MO_LEUQ); 2747 gen_helper_fildll_ST0(tcg_env, s->tmp1_i64); 2748 break; 2749 case 0x3f: /* fistpll */ 2750 gen_helper_fistll_ST0(s->tmp1_i64, tcg_env); 2751 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2752 s->mem_index, MO_LEUQ); 2753 gen_helper_fpop(tcg_env); 2754 break; 2755 default: 2756 return false; 2757 } 2758 2759 if (update_fdp) { 2760 int last_seg = s->override >= 0 ? s->override : a.def_seg; 2761 2762 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 2763 offsetof(CPUX86State, 2764 segs[last_seg].selector)); 2765 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 2766 offsetof(CPUX86State, fpds)); 2767 tcg_gen_st_tl(last_addr, tcg_env, 2768 offsetof(CPUX86State, fpdp)); 2769 } 2770 } else { 2771 /* register float ops */ 2772 int opreg = rm; 2773 2774 switch (op) { 2775 case 0x08: /* fld sti */ 2776 gen_helper_fpush(tcg_env); 2777 gen_helper_fmov_ST0_STN(tcg_env, 2778 tcg_constant_i32((opreg + 1) & 7)); 2779 break; 2780 case 0x09: /* fxchg sti */ 2781 case 0x29: /* fxchg4 sti, undocumented op */ 2782 case 0x39: /* fxchg7 sti, undocumented op */ 2783 gen_helper_fxchg_ST0_STN(tcg_env, tcg_constant_i32(opreg)); 2784 break; 2785 case 0x0a: /* grp d9/2 */ 2786 switch (rm) { 2787 case 0: /* fnop */ 2788 /* 2789 * check exceptions (FreeBSD FPU probe) 2790 * needs to be treated as I/O because of ferr_irq 2791 */ 2792 translator_io_start(&s->base); 2793 gen_helper_fwait(tcg_env); 2794 update_fip = false; 2795 break; 2796 default: 2797 return false; 2798 } 2799 break; 2800 case 0x0c: /* grp d9/4 */ 2801 switch (rm) { 2802 case 0: /* fchs */ 2803 gen_helper_fchs_ST0(tcg_env); 2804 break; 2805 case 1: /* fabs */ 2806 gen_helper_fabs_ST0(tcg_env); 2807 break; 2808 case 4: /* ftst */ 2809 gen_helper_fldz_FT0(tcg_env); 2810 gen_helper_fcom_ST0_FT0(tcg_env); 2811 break; 2812 case 5: /* fxam */ 2813 gen_helper_fxam_ST0(tcg_env); 2814 break; 2815 default: 2816 return false; 2817 } 2818 break; 2819 case 0x0d: /* grp d9/5 */ 2820 { 2821 switch (rm) { 2822 case 0: 2823 gen_helper_fpush(tcg_env); 2824 gen_helper_fld1_ST0(tcg_env); 2825 break; 2826 case 1: 2827 gen_helper_fpush(tcg_env); 2828 gen_helper_fldl2t_ST0(tcg_env); 2829 break; 2830 case 2: 2831 gen_helper_fpush(tcg_env); 2832 gen_helper_fldl2e_ST0(tcg_env); 2833 break; 2834 case 3: 2835 gen_helper_fpush(tcg_env); 2836 gen_helper_fldpi_ST0(tcg_env); 2837 break; 2838 case 4: 2839 gen_helper_fpush(tcg_env); 2840 gen_helper_fldlg2_ST0(tcg_env); 2841 break; 2842 case 5: 2843 gen_helper_fpush(tcg_env); 2844 gen_helper_fldln2_ST0(tcg_env); 2845 break; 2846 case 6: 2847 gen_helper_fpush(tcg_env); 2848 gen_helper_fldz_ST0(tcg_env); 2849 break; 2850 default: 2851 return false; 2852 } 2853 } 2854 break; 2855 case 0x0e: /* grp d9/6 */ 2856 switch (rm) { 2857 case 0: /* f2xm1 */ 2858 gen_helper_f2xm1(tcg_env); 2859 break; 2860 case 1: /* fyl2x */ 2861 gen_helper_fyl2x(tcg_env); 2862 break; 2863 case 2: /* fptan */ 2864 gen_helper_fptan(tcg_env); 2865 break; 2866 case 3: /* fpatan */ 2867 gen_helper_fpatan(tcg_env); 2868 break; 2869 case 4: /* fxtract */ 2870 gen_helper_fxtract(tcg_env); 2871 break; 2872 case 5: /* fprem1 */ 2873 gen_helper_fprem1(tcg_env); 2874 break; 2875 case 6: /* fdecstp */ 2876 gen_helper_fdecstp(tcg_env); 2877 break; 2878 default: 2879 case 7: /* fincstp */ 2880 gen_helper_fincstp(tcg_env); 2881 break; 2882 } 2883 break; 2884 case 0x0f: /* grp d9/7 */ 2885 switch (rm) { 2886 case 0: /* fprem */ 2887 gen_helper_fprem(tcg_env); 2888 break; 2889 case 1: /* fyl2xp1 */ 2890 gen_helper_fyl2xp1(tcg_env); 2891 break; 2892 case 2: /* fsqrt */ 2893 gen_helper_fsqrt(tcg_env); 2894 break; 2895 case 3: /* fsincos */ 2896 gen_helper_fsincos(tcg_env); 2897 break; 2898 case 5: /* fscale */ 2899 gen_helper_fscale(tcg_env); 2900 break; 2901 case 4: /* frndint */ 2902 gen_helper_frndint(tcg_env); 2903 break; 2904 case 6: /* fsin */ 2905 gen_helper_fsin(tcg_env); 2906 break; 2907 default: 2908 case 7: /* fcos */ 2909 gen_helper_fcos(tcg_env); 2910 break; 2911 } 2912 break; 2913 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 2914 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 2915 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 2916 { 2917 int op1; 2918 2919 op1 = op & 7; 2920 if (op >= 0x20) { 2921 gen_helper_fp_arith_STN_ST0(op1, opreg); 2922 if (op >= 0x30) { 2923 gen_helper_fpop(tcg_env); 2924 } 2925 } else { 2926 gen_helper_fmov_FT0_STN(tcg_env, 2927 tcg_constant_i32(opreg)); 2928 gen_helper_fp_arith_ST0_FT0(op1); 2929 } 2930 } 2931 break; 2932 case 0x02: /* fcom */ 2933 case 0x22: /* fcom2, undocumented op */ 2934 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2935 gen_helper_fcom_ST0_FT0(tcg_env); 2936 break; 2937 case 0x03: /* fcomp */ 2938 case 0x23: /* fcomp3, undocumented op */ 2939 case 0x32: /* fcomp5, undocumented op */ 2940 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2941 gen_helper_fcom_ST0_FT0(tcg_env); 2942 gen_helper_fpop(tcg_env); 2943 break; 2944 case 0x15: /* da/5 */ 2945 switch (rm) { 2946 case 1: /* fucompp */ 2947 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2948 gen_helper_fucom_ST0_FT0(tcg_env); 2949 gen_helper_fpop(tcg_env); 2950 gen_helper_fpop(tcg_env); 2951 break; 2952 default: 2953 return false; 2954 } 2955 break; 2956 case 0x1c: 2957 switch (rm) { 2958 case 0: /* feni (287 only, just do nop here) */ 2959 break; 2960 case 1: /* fdisi (287 only, just do nop here) */ 2961 break; 2962 case 2: /* fclex */ 2963 gen_helper_fclex(tcg_env); 2964 update_fip = false; 2965 break; 2966 case 3: /* fninit */ 2967 gen_helper_fninit(tcg_env); 2968 update_fip = false; 2969 break; 2970 case 4: /* fsetpm (287 only, just do nop here) */ 2971 break; 2972 default: 2973 return false; 2974 } 2975 break; 2976 case 0x1d: /* fucomi */ 2977 if (!(s->cpuid_features & CPUID_CMOV)) { 2978 goto illegal_op; 2979 } 2980 gen_update_cc_op(s); 2981 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2982 gen_helper_fucomi_ST0_FT0(tcg_env); 2983 set_cc_op(s, CC_OP_EFLAGS); 2984 break; 2985 case 0x1e: /* fcomi */ 2986 if (!(s->cpuid_features & CPUID_CMOV)) { 2987 goto illegal_op; 2988 } 2989 gen_update_cc_op(s); 2990 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2991 gen_helper_fcomi_ST0_FT0(tcg_env); 2992 set_cc_op(s, CC_OP_EFLAGS); 2993 break; 2994 case 0x28: /* ffree sti */ 2995 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2996 break; 2997 case 0x2a: /* fst sti */ 2998 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2999 break; 3000 case 0x2b: /* fstp sti */ 3001 case 0x0b: /* fstp1 sti, undocumented op */ 3002 case 0x3a: /* fstp8 sti, undocumented op */ 3003 case 0x3b: /* fstp9 sti, undocumented op */ 3004 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 3005 gen_helper_fpop(tcg_env); 3006 break; 3007 case 0x2c: /* fucom st(i) */ 3008 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 3009 gen_helper_fucom_ST0_FT0(tcg_env); 3010 break; 3011 case 0x2d: /* fucomp st(i) */ 3012 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 3013 gen_helper_fucom_ST0_FT0(tcg_env); 3014 gen_helper_fpop(tcg_env); 3015 break; 3016 case 0x33: /* de/3 */ 3017 switch (rm) { 3018 case 1: /* fcompp */ 3019 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 3020 gen_helper_fcom_ST0_FT0(tcg_env); 3021 gen_helper_fpop(tcg_env); 3022 gen_helper_fpop(tcg_env); 3023 break; 3024 default: 3025 return false; 3026 } 3027 break; 3028 case 0x38: /* ffreep sti, undocumented op */ 3029 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 3030 gen_helper_fpop(tcg_env); 3031 break; 3032 case 0x3c: /* df/4 */ 3033 switch (rm) { 3034 case 0: 3035 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 3036 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 3037 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3038 break; 3039 default: 3040 return false; 3041 } 3042 break; 3043 case 0x3d: /* fucomip */ 3044 if (!(s->cpuid_features & CPUID_CMOV)) { 3045 goto illegal_op; 3046 } 3047 gen_update_cc_op(s); 3048 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 3049 gen_helper_fucomi_ST0_FT0(tcg_env); 3050 gen_helper_fpop(tcg_env); 3051 set_cc_op(s, CC_OP_EFLAGS); 3052 break; 3053 case 0x3e: /* fcomip */ 3054 if (!(s->cpuid_features & CPUID_CMOV)) { 3055 goto illegal_op; 3056 } 3057 gen_update_cc_op(s); 3058 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 3059 gen_helper_fcomi_ST0_FT0(tcg_env); 3060 gen_helper_fpop(tcg_env); 3061 set_cc_op(s, CC_OP_EFLAGS); 3062 break; 3063 case 0x10 ... 0x13: /* fcmovxx */ 3064 case 0x18 ... 0x1b: 3065 { 3066 int op1; 3067 TCGLabel *l1; 3068 static const uint8_t fcmov_cc[8] = { 3069 (JCC_B << 1), 3070 (JCC_Z << 1), 3071 (JCC_BE << 1), 3072 (JCC_P << 1), 3073 }; 3074 3075 if (!(s->cpuid_features & CPUID_CMOV)) { 3076 goto illegal_op; 3077 } 3078 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 3079 l1 = gen_new_label(); 3080 gen_jcc1_noeob(s, op1, l1); 3081 gen_helper_fmov_ST0_STN(tcg_env, 3082 tcg_constant_i32(opreg)); 3083 gen_set_label(l1); 3084 } 3085 break; 3086 default: 3087 return false; 3088 } 3089 } 3090 3091 if (update_fip) { 3092 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 3093 offsetof(CPUX86State, segs[R_CS].selector)); 3094 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 3095 offsetof(CPUX86State, fpcs)); 3096 tcg_gen_st_tl(eip_cur_tl(s), 3097 tcg_env, offsetof(CPUX86State, fpip)); 3098 } 3099 return true; 3100 3101 illegal_op: 3102 gen_illegal_opcode(s); 3103 return true; 3104 } 3105 3106 static void disas_insn_old(DisasContext *s, CPUState *cpu, int b) 3107 { 3108 CPUX86State *env = cpu_env(cpu); 3109 int prefixes = s->prefix; 3110 MemOp dflag = s->dflag; 3111 int shift; 3112 MemOp ot; 3113 int modrm, reg, rm, mod, op, opreg, val; 3114 3115 /* now check op code */ 3116 switch (b) { 3117 /**************************/ 3118 /* arith & logic */ 3119 case 0x1c0: 3120 case 0x1c1: /* xadd Ev, Gv */ 3121 ot = mo_b_d(b, dflag); 3122 modrm = x86_ldub_code(env, s); 3123 reg = ((modrm >> 3) & 7) | REX_R(s); 3124 mod = (modrm >> 6) & 3; 3125 gen_op_mov_v_reg(s, ot, s->T0, reg); 3126 if (mod == 3) { 3127 rm = (modrm & 7) | REX_B(s); 3128 gen_op_mov_v_reg(s, ot, s->T1, rm); 3129 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3130 gen_op_mov_reg_v(s, ot, reg, s->T1); 3131 gen_op_mov_reg_v(s, ot, rm, s->T0); 3132 } else { 3133 gen_lea_modrm(env, s, modrm); 3134 if (s->prefix & PREFIX_LOCK) { 3135 tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0, 3136 s->mem_index, ot | MO_LE); 3137 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3138 } else { 3139 gen_op_ld_v(s, ot, s->T1, s->A0); 3140 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3141 gen_op_st_v(s, ot, s->T0, s->A0); 3142 } 3143 gen_op_mov_reg_v(s, ot, reg, s->T1); 3144 } 3145 gen_op_update2_cc(s); 3146 set_cc_op(s, CC_OP_ADDB + ot); 3147 break; 3148 case 0x1b0: 3149 case 0x1b1: /* cmpxchg Ev, Gv */ 3150 { 3151 TCGv oldv, newv, cmpv, dest; 3152 3153 ot = mo_b_d(b, dflag); 3154 modrm = x86_ldub_code(env, s); 3155 reg = ((modrm >> 3) & 7) | REX_R(s); 3156 mod = (modrm >> 6) & 3; 3157 oldv = tcg_temp_new(); 3158 newv = tcg_temp_new(); 3159 cmpv = tcg_temp_new(); 3160 gen_op_mov_v_reg(s, ot, newv, reg); 3161 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]); 3162 gen_extu(ot, cmpv); 3163 if (s->prefix & PREFIX_LOCK) { 3164 if (mod == 3) { 3165 goto illegal_op; 3166 } 3167 gen_lea_modrm(env, s, modrm); 3168 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv, 3169 s->mem_index, ot | MO_LE); 3170 } else { 3171 if (mod == 3) { 3172 rm = (modrm & 7) | REX_B(s); 3173 gen_op_mov_v_reg(s, ot, oldv, rm); 3174 gen_extu(ot, oldv); 3175 3176 /* 3177 * Unlike the memory case, where "the destination operand receives 3178 * a write cycle without regard to the result of the comparison", 3179 * rm must not be touched altogether if the write fails, including 3180 * not zero-extending it on 64-bit processors. So, precompute 3181 * the result of a successful writeback and perform the movcond 3182 * directly on cpu_regs. Also need to write accumulator first, in 3183 * case rm is part of RAX too. 3184 */ 3185 dest = gen_op_deposit_reg_v(s, ot, rm, newv, newv); 3186 tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, newv, dest); 3187 } else { 3188 gen_lea_modrm(env, s, modrm); 3189 gen_op_ld_v(s, ot, oldv, s->A0); 3190 3191 /* 3192 * Perform an unconditional store cycle like physical cpu; 3193 * must be before changing accumulator to ensure 3194 * idempotency if the store faults and the instruction 3195 * is restarted 3196 */ 3197 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv); 3198 gen_op_st_v(s, ot, newv, s->A0); 3199 } 3200 } 3201 /* 3202 * Write EAX only if the cmpxchg fails; reuse newv as the destination, 3203 * since it's dead here. 3204 */ 3205 dest = gen_op_deposit_reg_v(s, ot, R_EAX, newv, oldv); 3206 tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, dest, newv); 3207 tcg_gen_mov_tl(cpu_cc_src, oldv); 3208 tcg_gen_mov_tl(s->cc_srcT, cmpv); 3209 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv); 3210 set_cc_op(s, CC_OP_SUBB + ot); 3211 } 3212 break; 3213 case 0x1c7: /* cmpxchg8b */ 3214 modrm = x86_ldub_code(env, s); 3215 mod = (modrm >> 6) & 3; 3216 switch ((modrm >> 3) & 7) { 3217 case 1: /* CMPXCHG8, CMPXCHG16 */ 3218 if (mod == 3) { 3219 goto illegal_op; 3220 } 3221 #ifdef TARGET_X86_64 3222 if (dflag == MO_64) { 3223 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) { 3224 goto illegal_op; 3225 } 3226 gen_cmpxchg16b(s, env, modrm); 3227 break; 3228 } 3229 #endif 3230 if (!(s->cpuid_features & CPUID_CX8)) { 3231 goto illegal_op; 3232 } 3233 gen_cmpxchg8b(s, env, modrm); 3234 break; 3235 3236 case 7: /* RDSEED, RDPID with f3 prefix */ 3237 if (mod != 3 || 3238 (s->prefix & (PREFIX_LOCK | PREFIX_REPNZ))) { 3239 goto illegal_op; 3240 } 3241 if (s->prefix & PREFIX_REPZ) { 3242 if (!(s->cpuid_ext_features & CPUID_7_0_ECX_RDPID)) { 3243 goto illegal_op; 3244 } 3245 gen_helper_rdpid(s->T0, tcg_env); 3246 rm = (modrm & 7) | REX_B(s); 3247 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3248 break; 3249 } else { 3250 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) { 3251 goto illegal_op; 3252 } 3253 goto do_rdrand; 3254 } 3255 3256 case 6: /* RDRAND */ 3257 if (mod != 3 || 3258 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) || 3259 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { 3260 goto illegal_op; 3261 } 3262 do_rdrand: 3263 translator_io_start(&s->base); 3264 gen_helper_rdrand(s->T0, tcg_env); 3265 rm = (modrm & 7) | REX_B(s); 3266 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3267 set_cc_op(s, CC_OP_EFLAGS); 3268 break; 3269 3270 default: 3271 goto illegal_op; 3272 } 3273 break; 3274 3275 /**************************/ 3276 /* shifts */ 3277 case 0x1a4: /* shld imm */ 3278 op = 0; 3279 shift = 1; 3280 goto do_shiftd; 3281 case 0x1a5: /* shld cl */ 3282 op = 0; 3283 shift = 0; 3284 goto do_shiftd; 3285 case 0x1ac: /* shrd imm */ 3286 op = 1; 3287 shift = 1; 3288 goto do_shiftd; 3289 case 0x1ad: /* shrd cl */ 3290 op = 1; 3291 shift = 0; 3292 do_shiftd: 3293 ot = dflag; 3294 modrm = x86_ldub_code(env, s); 3295 mod = (modrm >> 6) & 3; 3296 rm = (modrm & 7) | REX_B(s); 3297 reg = ((modrm >> 3) & 7) | REX_R(s); 3298 if (mod != 3) { 3299 gen_lea_modrm(env, s, modrm); 3300 opreg = OR_TMP0; 3301 } else { 3302 opreg = rm; 3303 } 3304 gen_op_mov_v_reg(s, ot, s->T1, reg); 3305 3306 if (shift) { 3307 TCGv imm = tcg_constant_tl(x86_ldub_code(env, s)); 3308 gen_shiftd_rm_T1(s, ot, opreg, op, imm); 3309 } else { 3310 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]); 3311 } 3312 break; 3313 3314 /************************/ 3315 /* bit operations */ 3316 case 0x1ba: /* bt/bts/btr/btc Gv, im */ 3317 ot = dflag; 3318 modrm = x86_ldub_code(env, s); 3319 op = (modrm >> 3) & 7; 3320 mod = (modrm >> 6) & 3; 3321 rm = (modrm & 7) | REX_B(s); 3322 if (mod != 3) { 3323 s->rip_offset = 1; 3324 gen_lea_modrm(env, s, modrm); 3325 if (!(s->prefix & PREFIX_LOCK)) { 3326 gen_op_ld_v(s, ot, s->T0, s->A0); 3327 } 3328 } else { 3329 gen_op_mov_v_reg(s, ot, s->T0, rm); 3330 } 3331 /* load shift */ 3332 val = x86_ldub_code(env, s); 3333 tcg_gen_movi_tl(s->T1, val); 3334 if (op < 4) 3335 goto unknown_op; 3336 op -= 4; 3337 goto bt_op; 3338 case 0x1a3: /* bt Gv, Ev */ 3339 op = 0; 3340 goto do_btx; 3341 case 0x1ab: /* bts */ 3342 op = 1; 3343 goto do_btx; 3344 case 0x1b3: /* btr */ 3345 op = 2; 3346 goto do_btx; 3347 case 0x1bb: /* btc */ 3348 op = 3; 3349 do_btx: 3350 ot = dflag; 3351 modrm = x86_ldub_code(env, s); 3352 reg = ((modrm >> 3) & 7) | REX_R(s); 3353 mod = (modrm >> 6) & 3; 3354 rm = (modrm & 7) | REX_B(s); 3355 gen_op_mov_v_reg(s, MO_32, s->T1, reg); 3356 if (mod != 3) { 3357 AddressParts a = gen_lea_modrm_0(env, s, modrm); 3358 /* specific case: we need to add a displacement */ 3359 gen_exts(ot, s->T1); 3360 tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot); 3361 tcg_gen_shli_tl(s->tmp0, s->tmp0, ot); 3362 tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0); 3363 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 3364 if (!(s->prefix & PREFIX_LOCK)) { 3365 gen_op_ld_v(s, ot, s->T0, s->A0); 3366 } 3367 } else { 3368 gen_op_mov_v_reg(s, ot, s->T0, rm); 3369 } 3370 bt_op: 3371 tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1); 3372 tcg_gen_movi_tl(s->tmp0, 1); 3373 tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1); 3374 if (s->prefix & PREFIX_LOCK) { 3375 switch (op) { 3376 case 0: /* bt */ 3377 /* Needs no atomic ops; we suppressed the normal 3378 memory load for LOCK above so do it now. */ 3379 gen_op_ld_v(s, ot, s->T0, s->A0); 3380 break; 3381 case 1: /* bts */ 3382 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0, 3383 s->mem_index, ot | MO_LE); 3384 break; 3385 case 2: /* btr */ 3386 tcg_gen_not_tl(s->tmp0, s->tmp0); 3387 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0, 3388 s->mem_index, ot | MO_LE); 3389 break; 3390 default: 3391 case 3: /* btc */ 3392 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0, 3393 s->mem_index, ot | MO_LE); 3394 break; 3395 } 3396 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 3397 } else { 3398 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 3399 switch (op) { 3400 case 0: /* bt */ 3401 /* Data already loaded; nothing to do. */ 3402 break; 3403 case 1: /* bts */ 3404 tcg_gen_or_tl(s->T0, s->T0, s->tmp0); 3405 break; 3406 case 2: /* btr */ 3407 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0); 3408 break; 3409 default: 3410 case 3: /* btc */ 3411 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0); 3412 break; 3413 } 3414 if (op != 0) { 3415 if (mod != 3) { 3416 gen_op_st_v(s, ot, s->T0, s->A0); 3417 } else { 3418 gen_op_mov_reg_v(s, ot, rm, s->T0); 3419 } 3420 } 3421 } 3422 3423 /* Delay all CC updates until after the store above. Note that 3424 C is the result of the test, Z is unchanged, and the others 3425 are all undefined. */ 3426 switch (s->cc_op) { 3427 case CC_OP_MULB ... CC_OP_MULQ: 3428 case CC_OP_ADDB ... CC_OP_ADDQ: 3429 case CC_OP_ADCB ... CC_OP_ADCQ: 3430 case CC_OP_SUBB ... CC_OP_SUBQ: 3431 case CC_OP_SBBB ... CC_OP_SBBQ: 3432 case CC_OP_LOGICB ... CC_OP_LOGICQ: 3433 case CC_OP_INCB ... CC_OP_INCQ: 3434 case CC_OP_DECB ... CC_OP_DECQ: 3435 case CC_OP_SHLB ... CC_OP_SHLQ: 3436 case CC_OP_SARB ... CC_OP_SARQ: 3437 case CC_OP_BMILGB ... CC_OP_BMILGQ: 3438 /* Z was going to be computed from the non-zero status of CC_DST. 3439 We can get that same Z value (and the new C value) by leaving 3440 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the 3441 same width. */ 3442 tcg_gen_mov_tl(cpu_cc_src, s->tmp4); 3443 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB); 3444 break; 3445 default: 3446 /* Otherwise, generate EFLAGS and replace the C bit. */ 3447 gen_compute_eflags(s); 3448 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4, 3449 ctz32(CC_C), 1); 3450 break; 3451 } 3452 break; 3453 case 0x1bc: /* bsf / tzcnt */ 3454 case 0x1bd: /* bsr / lzcnt */ 3455 ot = dflag; 3456 modrm = x86_ldub_code(env, s); 3457 reg = ((modrm >> 3) & 7) | REX_R(s); 3458 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3459 gen_extu(ot, s->T0); 3460 3461 /* Note that lzcnt and tzcnt are in different extensions. */ 3462 if ((prefixes & PREFIX_REPZ) 3463 && (b & 1 3464 ? s->cpuid_ext3_features & CPUID_EXT3_ABM 3465 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) { 3466 int size = 8 << ot; 3467 /* For lzcnt/tzcnt, C bit is defined related to the input. */ 3468 tcg_gen_mov_tl(cpu_cc_src, s->T0); 3469 if (b & 1) { 3470 /* For lzcnt, reduce the target_ulong result by the 3471 number of zeros that we expect to find at the top. */ 3472 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS); 3473 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size); 3474 } else { 3475 /* For tzcnt, a zero input must return the operand size. */ 3476 tcg_gen_ctzi_tl(s->T0, s->T0, size); 3477 } 3478 /* For lzcnt/tzcnt, Z bit is defined related to the result. */ 3479 gen_op_update1_cc(s); 3480 set_cc_op(s, CC_OP_BMILGB + ot); 3481 } else { 3482 /* For bsr/bsf, only the Z bit is defined and it is related 3483 to the input and not the result. */ 3484 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3485 set_cc_op(s, CC_OP_LOGICB + ot); 3486 3487 /* ??? The manual says that the output is undefined when the 3488 input is zero, but real hardware leaves it unchanged, and 3489 real programs appear to depend on that. Accomplish this 3490 by passing the output as the value to return upon zero. */ 3491 if (b & 1) { 3492 /* For bsr, return the bit index of the first 1 bit, 3493 not the count of leading zeros. */ 3494 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1); 3495 tcg_gen_clz_tl(s->T0, s->T0, s->T1); 3496 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1); 3497 } else { 3498 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]); 3499 } 3500 } 3501 gen_op_mov_reg_v(s, ot, reg, s->T0); 3502 break; 3503 case 0x130: /* wrmsr */ 3504 case 0x132: /* rdmsr */ 3505 if (check_cpl0(s)) { 3506 gen_update_cc_op(s); 3507 gen_update_eip_cur(s); 3508 if (b & 2) { 3509 gen_helper_rdmsr(tcg_env); 3510 } else { 3511 gen_helper_wrmsr(tcg_env); 3512 s->base.is_jmp = DISAS_EOB_NEXT; 3513 } 3514 } 3515 break; 3516 case 0x131: /* rdtsc */ 3517 gen_update_cc_op(s); 3518 gen_update_eip_cur(s); 3519 translator_io_start(&s->base); 3520 gen_helper_rdtsc(tcg_env); 3521 break; 3522 case 0x133: /* rdpmc */ 3523 gen_update_cc_op(s); 3524 gen_update_eip_cur(s); 3525 gen_helper_rdpmc(tcg_env); 3526 s->base.is_jmp = DISAS_NORETURN; 3527 break; 3528 case 0x134: /* sysenter */ 3529 /* For AMD SYSENTER is not valid in long mode */ 3530 if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) { 3531 goto illegal_op; 3532 } 3533 if (!PE(s)) { 3534 gen_exception_gpf(s); 3535 } else { 3536 gen_helper_sysenter(tcg_env); 3537 s->base.is_jmp = DISAS_EOB_ONLY; 3538 } 3539 break; 3540 case 0x135: /* sysexit */ 3541 /* For AMD SYSEXIT is not valid in long mode */ 3542 if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) { 3543 goto illegal_op; 3544 } 3545 if (!PE(s) || CPL(s) != 0) { 3546 gen_exception_gpf(s); 3547 } else { 3548 gen_helper_sysexit(tcg_env, tcg_constant_i32(dflag - 1)); 3549 s->base.is_jmp = DISAS_EOB_ONLY; 3550 } 3551 break; 3552 case 0x105: /* syscall */ 3553 /* For Intel SYSCALL is only valid in long mode */ 3554 if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) { 3555 goto illegal_op; 3556 } 3557 gen_update_cc_op(s); 3558 gen_update_eip_cur(s); 3559 gen_helper_syscall(tcg_env, cur_insn_len_i32(s)); 3560 /* TF handling for the syscall insn is different. The TF bit is checked 3561 after the syscall insn completes. This allows #DB to not be 3562 generated after one has entered CPL0 if TF is set in FMASK. */ 3563 gen_eob_syscall(s); 3564 break; 3565 case 0x107: /* sysret */ 3566 /* For Intel SYSRET is only valid in long mode */ 3567 if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) { 3568 goto illegal_op; 3569 } 3570 if (!PE(s) || CPL(s) != 0) { 3571 gen_exception_gpf(s); 3572 } else { 3573 gen_helper_sysret(tcg_env, tcg_constant_i32(dflag - 1)); 3574 /* condition codes are modified only in long mode */ 3575 if (LMA(s)) { 3576 set_cc_op(s, CC_OP_EFLAGS); 3577 } 3578 /* TF handling for the sysret insn is different. The TF bit is 3579 checked after the sysret insn completes. This allows #DB to be 3580 generated "as if" the syscall insn in userspace has just 3581 completed. */ 3582 gen_eob_syscall(s); 3583 } 3584 break; 3585 case 0x1a2: /* cpuid */ 3586 gen_update_cc_op(s); 3587 gen_update_eip_cur(s); 3588 gen_helper_cpuid(tcg_env); 3589 break; 3590 case 0x100: 3591 modrm = x86_ldub_code(env, s); 3592 mod = (modrm >> 6) & 3; 3593 op = (modrm >> 3) & 7; 3594 switch(op) { 3595 case 0: /* sldt */ 3596 if (!PE(s) || VM86(s)) 3597 goto illegal_op; 3598 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3599 break; 3600 } 3601 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ); 3602 tcg_gen_ld32u_tl(s->T0, tcg_env, 3603 offsetof(CPUX86State, ldt.selector)); 3604 ot = mod == 3 ? dflag : MO_16; 3605 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 3606 break; 3607 case 2: /* lldt */ 3608 if (!PE(s) || VM86(s)) 3609 goto illegal_op; 3610 if (check_cpl0(s)) { 3611 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE); 3612 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3613 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3614 gen_helper_lldt(tcg_env, s->tmp2_i32); 3615 } 3616 break; 3617 case 1: /* str */ 3618 if (!PE(s) || VM86(s)) 3619 goto illegal_op; 3620 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3621 break; 3622 } 3623 gen_svm_check_intercept(s, SVM_EXIT_TR_READ); 3624 tcg_gen_ld32u_tl(s->T0, tcg_env, 3625 offsetof(CPUX86State, tr.selector)); 3626 ot = mod == 3 ? dflag : MO_16; 3627 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 3628 break; 3629 case 3: /* ltr */ 3630 if (!PE(s) || VM86(s)) 3631 goto illegal_op; 3632 if (check_cpl0(s)) { 3633 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE); 3634 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3635 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3636 gen_helper_ltr(tcg_env, s->tmp2_i32); 3637 } 3638 break; 3639 case 4: /* verr */ 3640 case 5: /* verw */ 3641 if (!PE(s) || VM86(s)) 3642 goto illegal_op; 3643 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3644 gen_update_cc_op(s); 3645 if (op == 4) { 3646 gen_helper_verr(tcg_env, s->T0); 3647 } else { 3648 gen_helper_verw(tcg_env, s->T0); 3649 } 3650 set_cc_op(s, CC_OP_EFLAGS); 3651 break; 3652 default: 3653 goto unknown_op; 3654 } 3655 break; 3656 3657 case 0x101: 3658 modrm = x86_ldub_code(env, s); 3659 switch (modrm) { 3660 CASE_MODRM_MEM_OP(0): /* sgdt */ 3661 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3662 break; 3663 } 3664 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ); 3665 gen_lea_modrm(env, s, modrm); 3666 tcg_gen_ld32u_tl(s->T0, 3667 tcg_env, offsetof(CPUX86State, gdt.limit)); 3668 gen_op_st_v(s, MO_16, s->T0, s->A0); 3669 gen_add_A0_im(s, 2); 3670 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3671 /* 3672 * NB: Despite a confusing description in Intel CPU documentation, 3673 * all 32-bits are written regardless of operand size. 3674 */ 3675 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3676 break; 3677 3678 case 0xc8: /* monitor */ 3679 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3680 goto illegal_op; 3681 } 3682 gen_update_cc_op(s); 3683 gen_update_eip_cur(s); 3684 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 3685 gen_add_A0_ds_seg(s); 3686 gen_helper_monitor(tcg_env, s->A0); 3687 break; 3688 3689 case 0xc9: /* mwait */ 3690 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3691 goto illegal_op; 3692 } 3693 gen_update_cc_op(s); 3694 gen_update_eip_cur(s); 3695 gen_helper_mwait(tcg_env, cur_insn_len_i32(s)); 3696 s->base.is_jmp = DISAS_NORETURN; 3697 break; 3698 3699 case 0xca: /* clac */ 3700 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3701 || CPL(s) != 0) { 3702 goto illegal_op; 3703 } 3704 gen_reset_eflags(s, AC_MASK); 3705 s->base.is_jmp = DISAS_EOB_NEXT; 3706 break; 3707 3708 case 0xcb: /* stac */ 3709 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3710 || CPL(s) != 0) { 3711 goto illegal_op; 3712 } 3713 gen_set_eflags(s, AC_MASK); 3714 s->base.is_jmp = DISAS_EOB_NEXT; 3715 break; 3716 3717 CASE_MODRM_MEM_OP(1): /* sidt */ 3718 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3719 break; 3720 } 3721 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ); 3722 gen_lea_modrm(env, s, modrm); 3723 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.limit)); 3724 gen_op_st_v(s, MO_16, s->T0, s->A0); 3725 gen_add_A0_im(s, 2); 3726 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3727 /* 3728 * NB: Despite a confusing description in Intel CPU documentation, 3729 * all 32-bits are written regardless of operand size. 3730 */ 3731 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3732 break; 3733 3734 case 0xd0: /* xgetbv */ 3735 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3736 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3737 | PREFIX_REPZ | PREFIX_REPNZ))) { 3738 goto illegal_op; 3739 } 3740 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3741 gen_helper_xgetbv(s->tmp1_i64, tcg_env, s->tmp2_i32); 3742 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3743 break; 3744 3745 case 0xd1: /* xsetbv */ 3746 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3747 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3748 | PREFIX_REPZ | PREFIX_REPNZ))) { 3749 goto illegal_op; 3750 } 3751 gen_svm_check_intercept(s, SVM_EXIT_XSETBV); 3752 if (!check_cpl0(s)) { 3753 break; 3754 } 3755 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3756 cpu_regs[R_EDX]); 3757 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3758 gen_helper_xsetbv(tcg_env, s->tmp2_i32, s->tmp1_i64); 3759 /* End TB because translation flags may change. */ 3760 s->base.is_jmp = DISAS_EOB_NEXT; 3761 break; 3762 3763 case 0xd8: /* VMRUN */ 3764 if (!SVME(s) || !PE(s)) { 3765 goto illegal_op; 3766 } 3767 if (!check_cpl0(s)) { 3768 break; 3769 } 3770 gen_update_cc_op(s); 3771 gen_update_eip_cur(s); 3772 gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1), 3773 cur_insn_len_i32(s)); 3774 tcg_gen_exit_tb(NULL, 0); 3775 s->base.is_jmp = DISAS_NORETURN; 3776 break; 3777 3778 case 0xd9: /* VMMCALL */ 3779 if (!SVME(s)) { 3780 goto illegal_op; 3781 } 3782 gen_update_cc_op(s); 3783 gen_update_eip_cur(s); 3784 gen_helper_vmmcall(tcg_env); 3785 break; 3786 3787 case 0xda: /* VMLOAD */ 3788 if (!SVME(s) || !PE(s)) { 3789 goto illegal_op; 3790 } 3791 if (!check_cpl0(s)) { 3792 break; 3793 } 3794 gen_update_cc_op(s); 3795 gen_update_eip_cur(s); 3796 gen_helper_vmload(tcg_env, tcg_constant_i32(s->aflag - 1)); 3797 break; 3798 3799 case 0xdb: /* VMSAVE */ 3800 if (!SVME(s) || !PE(s)) { 3801 goto illegal_op; 3802 } 3803 if (!check_cpl0(s)) { 3804 break; 3805 } 3806 gen_update_cc_op(s); 3807 gen_update_eip_cur(s); 3808 gen_helper_vmsave(tcg_env, tcg_constant_i32(s->aflag - 1)); 3809 break; 3810 3811 case 0xdc: /* STGI */ 3812 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3813 || !PE(s)) { 3814 goto illegal_op; 3815 } 3816 if (!check_cpl0(s)) { 3817 break; 3818 } 3819 gen_update_cc_op(s); 3820 gen_helper_stgi(tcg_env); 3821 s->base.is_jmp = DISAS_EOB_NEXT; 3822 break; 3823 3824 case 0xdd: /* CLGI */ 3825 if (!SVME(s) || !PE(s)) { 3826 goto illegal_op; 3827 } 3828 if (!check_cpl0(s)) { 3829 break; 3830 } 3831 gen_update_cc_op(s); 3832 gen_update_eip_cur(s); 3833 gen_helper_clgi(tcg_env); 3834 break; 3835 3836 case 0xde: /* SKINIT */ 3837 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3838 || !PE(s)) { 3839 goto illegal_op; 3840 } 3841 gen_svm_check_intercept(s, SVM_EXIT_SKINIT); 3842 /* If not intercepted, not implemented -- raise #UD. */ 3843 goto illegal_op; 3844 3845 case 0xdf: /* INVLPGA */ 3846 if (!SVME(s) || !PE(s)) { 3847 goto illegal_op; 3848 } 3849 if (!check_cpl0(s)) { 3850 break; 3851 } 3852 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA); 3853 if (s->aflag == MO_64) { 3854 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 3855 } else { 3856 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]); 3857 } 3858 gen_helper_flush_page(tcg_env, s->A0); 3859 s->base.is_jmp = DISAS_EOB_NEXT; 3860 break; 3861 3862 CASE_MODRM_MEM_OP(2): /* lgdt */ 3863 if (!check_cpl0(s)) { 3864 break; 3865 } 3866 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE); 3867 gen_lea_modrm(env, s, modrm); 3868 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3869 gen_add_A0_im(s, 2); 3870 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3871 if (dflag == MO_16) { 3872 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3873 } 3874 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3875 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, gdt.limit)); 3876 break; 3877 3878 CASE_MODRM_MEM_OP(3): /* lidt */ 3879 if (!check_cpl0(s)) { 3880 break; 3881 } 3882 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE); 3883 gen_lea_modrm(env, s, modrm); 3884 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3885 gen_add_A0_im(s, 2); 3886 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3887 if (dflag == MO_16) { 3888 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3889 } 3890 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3891 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, idt.limit)); 3892 break; 3893 3894 CASE_MODRM_OP(4): /* smsw */ 3895 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3896 break; 3897 } 3898 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0); 3899 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, cr[0])); 3900 /* 3901 * In 32-bit mode, the higher 16 bits of the destination 3902 * register are undefined. In practice CR0[31:0] is stored 3903 * just like in 64-bit mode. 3904 */ 3905 mod = (modrm >> 6) & 3; 3906 ot = (mod != 3 ? MO_16 : s->dflag); 3907 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 3908 break; 3909 case 0xee: /* rdpkru */ 3910 if (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3911 | PREFIX_REPZ | PREFIX_REPNZ)) { 3912 goto illegal_op; 3913 } 3914 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3915 gen_helper_rdpkru(s->tmp1_i64, tcg_env, s->tmp2_i32); 3916 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3917 break; 3918 case 0xef: /* wrpkru */ 3919 if (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3920 | PREFIX_REPZ | PREFIX_REPNZ)) { 3921 goto illegal_op; 3922 } 3923 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3924 cpu_regs[R_EDX]); 3925 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3926 gen_helper_wrpkru(tcg_env, s->tmp2_i32, s->tmp1_i64); 3927 break; 3928 3929 CASE_MODRM_OP(6): /* lmsw */ 3930 if (!check_cpl0(s)) { 3931 break; 3932 } 3933 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 3934 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3935 /* 3936 * Only the 4 lower bits of CR0 are modified. 3937 * PE cannot be set to zero if already set to one. 3938 */ 3939 tcg_gen_ld_tl(s->T1, tcg_env, offsetof(CPUX86State, cr[0])); 3940 tcg_gen_andi_tl(s->T0, s->T0, 0xf); 3941 tcg_gen_andi_tl(s->T1, s->T1, ~0xe); 3942 tcg_gen_or_tl(s->T0, s->T0, s->T1); 3943 gen_helper_write_crN(tcg_env, tcg_constant_i32(0), s->T0); 3944 s->base.is_jmp = DISAS_EOB_NEXT; 3945 break; 3946 3947 CASE_MODRM_MEM_OP(7): /* invlpg */ 3948 if (!check_cpl0(s)) { 3949 break; 3950 } 3951 gen_svm_check_intercept(s, SVM_EXIT_INVLPG); 3952 gen_lea_modrm(env, s, modrm); 3953 gen_helper_flush_page(tcg_env, s->A0); 3954 s->base.is_jmp = DISAS_EOB_NEXT; 3955 break; 3956 3957 case 0xf8: /* swapgs */ 3958 #ifdef TARGET_X86_64 3959 if (CODE64(s)) { 3960 if (check_cpl0(s)) { 3961 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]); 3962 tcg_gen_ld_tl(cpu_seg_base[R_GS], tcg_env, 3963 offsetof(CPUX86State, kernelgsbase)); 3964 tcg_gen_st_tl(s->T0, tcg_env, 3965 offsetof(CPUX86State, kernelgsbase)); 3966 } 3967 break; 3968 } 3969 #endif 3970 goto illegal_op; 3971 3972 case 0xf9: /* rdtscp */ 3973 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) { 3974 goto illegal_op; 3975 } 3976 gen_update_cc_op(s); 3977 gen_update_eip_cur(s); 3978 translator_io_start(&s->base); 3979 gen_helper_rdtsc(tcg_env); 3980 gen_helper_rdpid(s->T0, tcg_env); 3981 gen_op_mov_reg_v(s, dflag, R_ECX, s->T0); 3982 break; 3983 3984 default: 3985 goto unknown_op; 3986 } 3987 break; 3988 3989 case 0x108: /* invd */ 3990 case 0x109: /* wbinvd; wbnoinvd with REPZ prefix */ 3991 if (check_cpl0(s)) { 3992 gen_svm_check_intercept(s, (b & 1) ? SVM_EXIT_WBINVD : SVM_EXIT_INVD); 3993 /* nothing to do */ 3994 } 3995 break; 3996 case 0x102: /* lar */ 3997 case 0x103: /* lsl */ 3998 { 3999 TCGLabel *label1; 4000 TCGv t0; 4001 if (!PE(s) || VM86(s)) 4002 goto illegal_op; 4003 ot = dflag != MO_16 ? MO_32 : MO_16; 4004 modrm = x86_ldub_code(env, s); 4005 reg = ((modrm >> 3) & 7) | REX_R(s); 4006 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 4007 t0 = tcg_temp_new(); 4008 gen_update_cc_op(s); 4009 if (b == 0x102) { 4010 gen_helper_lar(t0, tcg_env, s->T0); 4011 } else { 4012 gen_helper_lsl(t0, tcg_env, s->T0); 4013 } 4014 tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z); 4015 label1 = gen_new_label(); 4016 tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1); 4017 gen_op_mov_reg_v(s, ot, reg, t0); 4018 gen_set_label(label1); 4019 set_cc_op(s, CC_OP_EFLAGS); 4020 } 4021 break; 4022 case 0x11a: 4023 modrm = x86_ldub_code(env, s); 4024 if (s->flags & HF_MPX_EN_MASK) { 4025 mod = (modrm >> 6) & 3; 4026 reg = ((modrm >> 3) & 7) | REX_R(s); 4027 if (prefixes & PREFIX_REPZ) { 4028 /* bndcl */ 4029 if (reg >= 4 4030 || (prefixes & PREFIX_LOCK) 4031 || s->aflag == MO_16) { 4032 goto illegal_op; 4033 } 4034 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]); 4035 } else if (prefixes & PREFIX_REPNZ) { 4036 /* bndcu */ 4037 if (reg >= 4 4038 || (prefixes & PREFIX_LOCK) 4039 || s->aflag == MO_16) { 4040 goto illegal_op; 4041 } 4042 TCGv_i64 notu = tcg_temp_new_i64(); 4043 tcg_gen_not_i64(notu, cpu_bndu[reg]); 4044 gen_bndck(env, s, modrm, TCG_COND_GTU, notu); 4045 } else if (prefixes & PREFIX_DATA) { 4046 /* bndmov -- from reg/mem */ 4047 if (reg >= 4 || s->aflag == MO_16) { 4048 goto illegal_op; 4049 } 4050 if (mod == 3) { 4051 int reg2 = (modrm & 7) | REX_B(s); 4052 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 4053 goto illegal_op; 4054 } 4055 if (s->flags & HF_MPX_IU_MASK) { 4056 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]); 4057 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]); 4058 } 4059 } else { 4060 gen_lea_modrm(env, s, modrm); 4061 if (CODE64(s)) { 4062 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 4063 s->mem_index, MO_LEUQ); 4064 tcg_gen_addi_tl(s->A0, s->A0, 8); 4065 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 4066 s->mem_index, MO_LEUQ); 4067 } else { 4068 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 4069 s->mem_index, MO_LEUL); 4070 tcg_gen_addi_tl(s->A0, s->A0, 4); 4071 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 4072 s->mem_index, MO_LEUL); 4073 } 4074 /* bnd registers are now in-use */ 4075 gen_set_hflag(s, HF_MPX_IU_MASK); 4076 } 4077 } else if (mod != 3) { 4078 /* bndldx */ 4079 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4080 if (reg >= 4 4081 || (prefixes & PREFIX_LOCK) 4082 || s->aflag == MO_16 4083 || a.base < -1) { 4084 goto illegal_op; 4085 } 4086 if (a.base >= 0) { 4087 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 4088 } else { 4089 tcg_gen_movi_tl(s->A0, 0); 4090 } 4091 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 4092 if (a.index >= 0) { 4093 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 4094 } else { 4095 tcg_gen_movi_tl(s->T0, 0); 4096 } 4097 if (CODE64(s)) { 4098 gen_helper_bndldx64(cpu_bndl[reg], tcg_env, s->A0, s->T0); 4099 tcg_gen_ld_i64(cpu_bndu[reg], tcg_env, 4100 offsetof(CPUX86State, mmx_t0.MMX_Q(0))); 4101 } else { 4102 gen_helper_bndldx32(cpu_bndu[reg], tcg_env, s->A0, s->T0); 4103 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]); 4104 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32); 4105 } 4106 gen_set_hflag(s, HF_MPX_IU_MASK); 4107 } 4108 } 4109 gen_nop_modrm(env, s, modrm); 4110 break; 4111 case 0x11b: 4112 modrm = x86_ldub_code(env, s); 4113 if (s->flags & HF_MPX_EN_MASK) { 4114 mod = (modrm >> 6) & 3; 4115 reg = ((modrm >> 3) & 7) | REX_R(s); 4116 if (mod != 3 && (prefixes & PREFIX_REPZ)) { 4117 /* bndmk */ 4118 if (reg >= 4 4119 || (prefixes & PREFIX_LOCK) 4120 || s->aflag == MO_16) { 4121 goto illegal_op; 4122 } 4123 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4124 if (a.base >= 0) { 4125 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]); 4126 if (!CODE64(s)) { 4127 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]); 4128 } 4129 } else if (a.base == -1) { 4130 /* no base register has lower bound of 0 */ 4131 tcg_gen_movi_i64(cpu_bndl[reg], 0); 4132 } else { 4133 /* rip-relative generates #ud */ 4134 goto illegal_op; 4135 } 4136 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false)); 4137 if (!CODE64(s)) { 4138 tcg_gen_ext32u_tl(s->A0, s->A0); 4139 } 4140 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0); 4141 /* bnd registers are now in-use */ 4142 gen_set_hflag(s, HF_MPX_IU_MASK); 4143 break; 4144 } else if (prefixes & PREFIX_REPNZ) { 4145 /* bndcn */ 4146 if (reg >= 4 4147 || (prefixes & PREFIX_LOCK) 4148 || s->aflag == MO_16) { 4149 goto illegal_op; 4150 } 4151 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]); 4152 } else if (prefixes & PREFIX_DATA) { 4153 /* bndmov -- to reg/mem */ 4154 if (reg >= 4 || s->aflag == MO_16) { 4155 goto illegal_op; 4156 } 4157 if (mod == 3) { 4158 int reg2 = (modrm & 7) | REX_B(s); 4159 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 4160 goto illegal_op; 4161 } 4162 if (s->flags & HF_MPX_IU_MASK) { 4163 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]); 4164 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]); 4165 } 4166 } else { 4167 gen_lea_modrm(env, s, modrm); 4168 if (CODE64(s)) { 4169 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 4170 s->mem_index, MO_LEUQ); 4171 tcg_gen_addi_tl(s->A0, s->A0, 8); 4172 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 4173 s->mem_index, MO_LEUQ); 4174 } else { 4175 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 4176 s->mem_index, MO_LEUL); 4177 tcg_gen_addi_tl(s->A0, s->A0, 4); 4178 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 4179 s->mem_index, MO_LEUL); 4180 } 4181 } 4182 } else if (mod != 3) { 4183 /* bndstx */ 4184 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4185 if (reg >= 4 4186 || (prefixes & PREFIX_LOCK) 4187 || s->aflag == MO_16 4188 || a.base < -1) { 4189 goto illegal_op; 4190 } 4191 if (a.base >= 0) { 4192 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 4193 } else { 4194 tcg_gen_movi_tl(s->A0, 0); 4195 } 4196 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 4197 if (a.index >= 0) { 4198 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 4199 } else { 4200 tcg_gen_movi_tl(s->T0, 0); 4201 } 4202 if (CODE64(s)) { 4203 gen_helper_bndstx64(tcg_env, s->A0, s->T0, 4204 cpu_bndl[reg], cpu_bndu[reg]); 4205 } else { 4206 gen_helper_bndstx32(tcg_env, s->A0, s->T0, 4207 cpu_bndl[reg], cpu_bndu[reg]); 4208 } 4209 } 4210 } 4211 gen_nop_modrm(env, s, modrm); 4212 break; 4213 4214 case 0x120: /* mov reg, crN */ 4215 case 0x122: /* mov crN, reg */ 4216 if (!check_cpl0(s)) { 4217 break; 4218 } 4219 modrm = x86_ldub_code(env, s); 4220 /* 4221 * Ignore the mod bits (assume (modrm&0xc0)==0xc0). 4222 * AMD documentation (24594.pdf) and testing of Intel 386 and 486 4223 * processors all show that the mod bits are assumed to be 1's, 4224 * regardless of actual values. 4225 */ 4226 rm = (modrm & 7) | REX_B(s); 4227 reg = ((modrm >> 3) & 7) | REX_R(s); 4228 switch (reg) { 4229 case 0: 4230 if ((prefixes & PREFIX_LOCK) && 4231 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) { 4232 reg = 8; 4233 } 4234 break; 4235 case 2: 4236 case 3: 4237 case 4: 4238 case 8: 4239 break; 4240 default: 4241 goto unknown_op; 4242 } 4243 ot = (CODE64(s) ? MO_64 : MO_32); 4244 4245 translator_io_start(&s->base); 4246 if (b & 2) { 4247 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg); 4248 gen_op_mov_v_reg(s, ot, s->T0, rm); 4249 gen_helper_write_crN(tcg_env, tcg_constant_i32(reg), s->T0); 4250 s->base.is_jmp = DISAS_EOB_NEXT; 4251 } else { 4252 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg); 4253 gen_helper_read_crN(s->T0, tcg_env, tcg_constant_i32(reg)); 4254 gen_op_mov_reg_v(s, ot, rm, s->T0); 4255 } 4256 break; 4257 4258 case 0x121: /* mov reg, drN */ 4259 case 0x123: /* mov drN, reg */ 4260 if (check_cpl0(s)) { 4261 modrm = x86_ldub_code(env, s); 4262 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). 4263 * AMD documentation (24594.pdf) and testing of 4264 * intel 386 and 486 processors all show that the mod bits 4265 * are assumed to be 1's, regardless of actual values. 4266 */ 4267 rm = (modrm & 7) | REX_B(s); 4268 reg = ((modrm >> 3) & 7) | REX_R(s); 4269 if (CODE64(s)) 4270 ot = MO_64; 4271 else 4272 ot = MO_32; 4273 if (reg >= 8) { 4274 goto illegal_op; 4275 } 4276 if (b & 2) { 4277 gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg); 4278 gen_op_mov_v_reg(s, ot, s->T0, rm); 4279 tcg_gen_movi_i32(s->tmp2_i32, reg); 4280 gen_helper_set_dr(tcg_env, s->tmp2_i32, s->T0); 4281 s->base.is_jmp = DISAS_EOB_NEXT; 4282 } else { 4283 gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg); 4284 tcg_gen_movi_i32(s->tmp2_i32, reg); 4285 gen_helper_get_dr(s->T0, tcg_env, s->tmp2_i32); 4286 gen_op_mov_reg_v(s, ot, rm, s->T0); 4287 } 4288 } 4289 break; 4290 case 0x106: /* clts */ 4291 if (check_cpl0(s)) { 4292 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 4293 gen_helper_clts(tcg_env); 4294 /* abort block because static cpu state changed */ 4295 s->base.is_jmp = DISAS_EOB_NEXT; 4296 } 4297 break; 4298 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */ 4299 case 0x1ae: 4300 modrm = x86_ldub_code(env, s); 4301 switch (modrm) { 4302 CASE_MODRM_MEM_OP(0): /* fxsave */ 4303 if (!(s->cpuid_features & CPUID_FXSR) 4304 || (prefixes & PREFIX_LOCK)) { 4305 goto illegal_op; 4306 } 4307 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 4308 gen_exception(s, EXCP07_PREX); 4309 break; 4310 } 4311 gen_lea_modrm(env, s, modrm); 4312 gen_helper_fxsave(tcg_env, s->A0); 4313 break; 4314 4315 CASE_MODRM_MEM_OP(1): /* fxrstor */ 4316 if (!(s->cpuid_features & CPUID_FXSR) 4317 || (prefixes & PREFIX_LOCK)) { 4318 goto illegal_op; 4319 } 4320 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 4321 gen_exception(s, EXCP07_PREX); 4322 break; 4323 } 4324 gen_lea_modrm(env, s, modrm); 4325 gen_helper_fxrstor(tcg_env, s->A0); 4326 break; 4327 4328 CASE_MODRM_MEM_OP(2): /* ldmxcsr */ 4329 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 4330 goto illegal_op; 4331 } 4332 if (s->flags & HF_TS_MASK) { 4333 gen_exception(s, EXCP07_PREX); 4334 break; 4335 } 4336 gen_lea_modrm(env, s, modrm); 4337 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL); 4338 gen_helper_ldmxcsr(tcg_env, s->tmp2_i32); 4339 break; 4340 4341 CASE_MODRM_MEM_OP(3): /* stmxcsr */ 4342 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 4343 goto illegal_op; 4344 } 4345 if (s->flags & HF_TS_MASK) { 4346 gen_exception(s, EXCP07_PREX); 4347 break; 4348 } 4349 gen_helper_update_mxcsr(tcg_env); 4350 gen_lea_modrm(env, s, modrm); 4351 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, mxcsr)); 4352 gen_op_st_v(s, MO_32, s->T0, s->A0); 4353 break; 4354 4355 CASE_MODRM_MEM_OP(4): /* xsave */ 4356 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 4357 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 4358 | PREFIX_REPZ | PREFIX_REPNZ))) { 4359 goto illegal_op; 4360 } 4361 gen_lea_modrm(env, s, modrm); 4362 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 4363 cpu_regs[R_EDX]); 4364 gen_helper_xsave(tcg_env, s->A0, s->tmp1_i64); 4365 break; 4366 4367 CASE_MODRM_MEM_OP(5): /* xrstor */ 4368 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 4369 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 4370 | PREFIX_REPZ | PREFIX_REPNZ))) { 4371 goto illegal_op; 4372 } 4373 gen_lea_modrm(env, s, modrm); 4374 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 4375 cpu_regs[R_EDX]); 4376 gen_helper_xrstor(tcg_env, s->A0, s->tmp1_i64); 4377 /* XRSTOR is how MPX is enabled, which changes how 4378 we translate. Thus we need to end the TB. */ 4379 s->base.is_jmp = DISAS_EOB_NEXT; 4380 break; 4381 4382 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */ 4383 if (prefixes & PREFIX_LOCK) { 4384 goto illegal_op; 4385 } 4386 if (prefixes & PREFIX_DATA) { 4387 /* clwb */ 4388 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) { 4389 goto illegal_op; 4390 } 4391 gen_nop_modrm(env, s, modrm); 4392 } else { 4393 /* xsaveopt */ 4394 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 4395 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0 4396 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) { 4397 goto illegal_op; 4398 } 4399 gen_lea_modrm(env, s, modrm); 4400 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 4401 cpu_regs[R_EDX]); 4402 gen_helper_xsaveopt(tcg_env, s->A0, s->tmp1_i64); 4403 } 4404 break; 4405 4406 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */ 4407 if (prefixes & PREFIX_LOCK) { 4408 goto illegal_op; 4409 } 4410 if (prefixes & PREFIX_DATA) { 4411 /* clflushopt */ 4412 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) { 4413 goto illegal_op; 4414 } 4415 } else { 4416 /* clflush */ 4417 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) 4418 || !(s->cpuid_features & CPUID_CLFLUSH)) { 4419 goto illegal_op; 4420 } 4421 } 4422 gen_nop_modrm(env, s, modrm); 4423 break; 4424 4425 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */ 4426 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */ 4427 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */ 4428 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */ 4429 if (CODE64(s) 4430 && (prefixes & PREFIX_REPZ) 4431 && !(prefixes & PREFIX_LOCK) 4432 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) { 4433 TCGv base, treg, src, dst; 4434 4435 /* Preserve hflags bits by testing CR4 at runtime. */ 4436 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK); 4437 gen_helper_cr4_testbit(tcg_env, s->tmp2_i32); 4438 4439 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS]; 4440 treg = cpu_regs[(modrm & 7) | REX_B(s)]; 4441 4442 if (modrm & 0x10) { 4443 /* wr*base */ 4444 dst = base, src = treg; 4445 } else { 4446 /* rd*base */ 4447 dst = treg, src = base; 4448 } 4449 4450 if (s->dflag == MO_32) { 4451 tcg_gen_ext32u_tl(dst, src); 4452 } else { 4453 tcg_gen_mov_tl(dst, src); 4454 } 4455 break; 4456 } 4457 goto unknown_op; 4458 4459 case 0xf8 ... 0xff: /* sfence */ 4460 if (!(s->cpuid_features & CPUID_SSE) 4461 || (prefixes & PREFIX_LOCK)) { 4462 goto illegal_op; 4463 } 4464 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC); 4465 break; 4466 case 0xe8 ... 0xef: /* lfence */ 4467 if (!(s->cpuid_features & CPUID_SSE) 4468 || (prefixes & PREFIX_LOCK)) { 4469 goto illegal_op; 4470 } 4471 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC); 4472 break; 4473 case 0xf0 ... 0xf7: /* mfence */ 4474 if (!(s->cpuid_features & CPUID_SSE2) 4475 || (prefixes & PREFIX_LOCK)) { 4476 goto illegal_op; 4477 } 4478 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 4479 break; 4480 4481 default: 4482 goto unknown_op; 4483 } 4484 break; 4485 4486 case 0x1aa: /* rsm */ 4487 gen_svm_check_intercept(s, SVM_EXIT_RSM); 4488 if (!(s->flags & HF_SMM_MASK)) 4489 goto illegal_op; 4490 #ifdef CONFIG_USER_ONLY 4491 /* we should not be in SMM mode */ 4492 g_assert_not_reached(); 4493 #else 4494 gen_update_cc_op(s); 4495 gen_update_eip_next(s); 4496 gen_helper_rsm(tcg_env); 4497 #endif /* CONFIG_USER_ONLY */ 4498 s->base.is_jmp = DISAS_EOB_ONLY; 4499 break; 4500 case 0x1b8: /* SSE4.2 popcnt */ 4501 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) != 4502 PREFIX_REPZ) 4503 goto illegal_op; 4504 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT)) 4505 goto illegal_op; 4506 4507 modrm = x86_ldub_code(env, s); 4508 reg = ((modrm >> 3) & 7) | REX_R(s); 4509 4510 ot = dflag; 4511 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 4512 gen_extu(ot, s->T0); 4513 tcg_gen_mov_tl(cpu_cc_src, s->T0); 4514 tcg_gen_ctpop_tl(s->T0, s->T0); 4515 gen_op_mov_reg_v(s, ot, reg, s->T0); 4516 4517 set_cc_op(s, CC_OP_POPCNT); 4518 break; 4519 default: 4520 g_assert_not_reached(); 4521 } 4522 return; 4523 illegal_op: 4524 gen_illegal_opcode(s); 4525 return; 4526 unknown_op: 4527 gen_unknown_opcode(env, s); 4528 } 4529 4530 #include "decode-new.h" 4531 #include "emit.c.inc" 4532 #include "decode-new.c.inc" 4533 4534 void tcg_x86_init(void) 4535 { 4536 static const char reg_names[CPU_NB_REGS][4] = { 4537 #ifdef TARGET_X86_64 4538 [R_EAX] = "rax", 4539 [R_EBX] = "rbx", 4540 [R_ECX] = "rcx", 4541 [R_EDX] = "rdx", 4542 [R_ESI] = "rsi", 4543 [R_EDI] = "rdi", 4544 [R_EBP] = "rbp", 4545 [R_ESP] = "rsp", 4546 [8] = "r8", 4547 [9] = "r9", 4548 [10] = "r10", 4549 [11] = "r11", 4550 [12] = "r12", 4551 [13] = "r13", 4552 [14] = "r14", 4553 [15] = "r15", 4554 #else 4555 [R_EAX] = "eax", 4556 [R_EBX] = "ebx", 4557 [R_ECX] = "ecx", 4558 [R_EDX] = "edx", 4559 [R_ESI] = "esi", 4560 [R_EDI] = "edi", 4561 [R_EBP] = "ebp", 4562 [R_ESP] = "esp", 4563 #endif 4564 }; 4565 static const char eip_name[] = { 4566 #ifdef TARGET_X86_64 4567 "rip" 4568 #else 4569 "eip" 4570 #endif 4571 }; 4572 static const char seg_base_names[6][8] = { 4573 [R_CS] = "cs_base", 4574 [R_DS] = "ds_base", 4575 [R_ES] = "es_base", 4576 [R_FS] = "fs_base", 4577 [R_GS] = "gs_base", 4578 [R_SS] = "ss_base", 4579 }; 4580 static const char bnd_regl_names[4][8] = { 4581 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb" 4582 }; 4583 static const char bnd_regu_names[4][8] = { 4584 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" 4585 }; 4586 int i; 4587 4588 cpu_cc_op = tcg_global_mem_new_i32(tcg_env, 4589 offsetof(CPUX86State, cc_op), "cc_op"); 4590 cpu_cc_dst = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_dst), 4591 "cc_dst"); 4592 cpu_cc_src = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src), 4593 "cc_src"); 4594 cpu_cc_src2 = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src2), 4595 "cc_src2"); 4596 cpu_eip = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, eip), eip_name); 4597 4598 for (i = 0; i < CPU_NB_REGS; ++i) { 4599 cpu_regs[i] = tcg_global_mem_new(tcg_env, 4600 offsetof(CPUX86State, regs[i]), 4601 reg_names[i]); 4602 } 4603 4604 for (i = 0; i < 6; ++i) { 4605 cpu_seg_base[i] 4606 = tcg_global_mem_new(tcg_env, 4607 offsetof(CPUX86State, segs[i].base), 4608 seg_base_names[i]); 4609 } 4610 4611 for (i = 0; i < 4; ++i) { 4612 cpu_bndl[i] 4613 = tcg_global_mem_new_i64(tcg_env, 4614 offsetof(CPUX86State, bnd_regs[i].lb), 4615 bnd_regl_names[i]); 4616 cpu_bndu[i] 4617 = tcg_global_mem_new_i64(tcg_env, 4618 offsetof(CPUX86State, bnd_regs[i].ub), 4619 bnd_regu_names[i]); 4620 } 4621 } 4622 4623 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 4624 { 4625 DisasContext *dc = container_of(dcbase, DisasContext, base); 4626 CPUX86State *env = cpu_env(cpu); 4627 uint32_t flags = dc->base.tb->flags; 4628 uint32_t cflags = tb_cflags(dc->base.tb); 4629 int cpl = (flags >> HF_CPL_SHIFT) & 3; 4630 int iopl = (flags >> IOPL_SHIFT) & 3; 4631 4632 dc->cs_base = dc->base.tb->cs_base; 4633 dc->pc_save = dc->base.pc_next; 4634 dc->flags = flags; 4635 #ifndef CONFIG_USER_ONLY 4636 dc->cpl = cpl; 4637 dc->iopl = iopl; 4638 #endif 4639 4640 /* We make some simplifying assumptions; validate they're correct. */ 4641 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); 4642 g_assert(CPL(dc) == cpl); 4643 g_assert(IOPL(dc) == iopl); 4644 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0)); 4645 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0)); 4646 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0)); 4647 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0)); 4648 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0)); 4649 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0)); 4650 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0)); 4651 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0)); 4652 4653 dc->cc_op = CC_OP_DYNAMIC; 4654 dc->cc_op_dirty = false; 4655 /* select memory access functions */ 4656 dc->mem_index = cpu_mmu_index(cpu, false); 4657 dc->cpuid_features = env->features[FEAT_1_EDX]; 4658 dc->cpuid_ext_features = env->features[FEAT_1_ECX]; 4659 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; 4660 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; 4661 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; 4662 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX]; 4663 dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX]; 4664 dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; 4665 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || 4666 (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 4667 /* 4668 * If jmp_opt, we want to handle each string instruction individually. 4669 * For icount also disable repz optimization so that each iteration 4670 * is accounted separately. 4671 */ 4672 dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT); 4673 4674 dc->T0 = tcg_temp_new(); 4675 dc->T1 = tcg_temp_new(); 4676 dc->A0 = tcg_temp_new(); 4677 4678 dc->tmp0 = tcg_temp_new(); 4679 dc->tmp1_i64 = tcg_temp_new_i64(); 4680 dc->tmp2_i32 = tcg_temp_new_i32(); 4681 dc->tmp3_i32 = tcg_temp_new_i32(); 4682 dc->tmp4 = tcg_temp_new(); 4683 dc->cc_srcT = tcg_temp_new(); 4684 } 4685 4686 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) 4687 { 4688 } 4689 4690 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 4691 { 4692 DisasContext *dc = container_of(dcbase, DisasContext, base); 4693 target_ulong pc_arg = dc->base.pc_next; 4694 4695 dc->prev_insn_start = dc->base.insn_start; 4696 dc->prev_insn_end = tcg_last_op(); 4697 if (tb_cflags(dcbase->tb) & CF_PCREL) { 4698 pc_arg &= ~TARGET_PAGE_MASK; 4699 } 4700 tcg_gen_insn_start(pc_arg, dc->cc_op); 4701 } 4702 4703 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 4704 { 4705 DisasContext *dc = container_of(dcbase, DisasContext, base); 4706 bool orig_cc_op_dirty = dc->cc_op_dirty; 4707 CCOp orig_cc_op = dc->cc_op; 4708 target_ulong orig_pc_save = dc->pc_save; 4709 4710 #ifdef TARGET_VSYSCALL_PAGE 4711 /* 4712 * Detect entry into the vsyscall page and invoke the syscall. 4713 */ 4714 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) { 4715 gen_exception(dc, EXCP_VSYSCALL); 4716 dc->base.pc_next = dc->pc + 1; 4717 return; 4718 } 4719 #endif 4720 4721 switch (sigsetjmp(dc->jmpbuf, 0)) { 4722 case 0: 4723 disas_insn(dc, cpu); 4724 break; 4725 case 1: 4726 gen_exception_gpf(dc); 4727 break; 4728 case 2: 4729 /* Restore state that may affect the next instruction. */ 4730 dc->pc = dc->base.pc_next; 4731 /* 4732 * TODO: These save/restore can be removed after the table-based 4733 * decoder is complete; we will be decoding the insn completely 4734 * before any code generation that might affect these variables. 4735 */ 4736 dc->cc_op_dirty = orig_cc_op_dirty; 4737 dc->cc_op = orig_cc_op; 4738 dc->pc_save = orig_pc_save; 4739 /* END TODO */ 4740 dc->base.num_insns--; 4741 tcg_remove_ops_after(dc->prev_insn_end); 4742 dc->base.insn_start = dc->prev_insn_start; 4743 dc->base.is_jmp = DISAS_TOO_MANY; 4744 return; 4745 default: 4746 g_assert_not_reached(); 4747 } 4748 4749 /* 4750 * Instruction decoding completed (possibly with #GP if the 4751 * 15-byte boundary was exceeded). 4752 */ 4753 dc->base.pc_next = dc->pc; 4754 if (dc->base.is_jmp == DISAS_NEXT) { 4755 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) { 4756 /* 4757 * If single step mode, we generate only one instruction and 4758 * generate an exception. 4759 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 4760 * the flag and abort the translation to give the irqs a 4761 * chance to happen. 4762 */ 4763 dc->base.is_jmp = DISAS_EOB_NEXT; 4764 } else if (!is_same_page(&dc->base, dc->base.pc_next)) { 4765 dc->base.is_jmp = DISAS_TOO_MANY; 4766 } 4767 } 4768 } 4769 4770 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 4771 { 4772 DisasContext *dc = container_of(dcbase, DisasContext, base); 4773 4774 switch (dc->base.is_jmp) { 4775 case DISAS_NORETURN: 4776 break; 4777 case DISAS_TOO_MANY: 4778 gen_update_cc_op(dc); 4779 gen_jmp_rel_csize(dc, 0, 0); 4780 break; 4781 case DISAS_EOB_NEXT: 4782 gen_update_cc_op(dc); 4783 gen_update_eip_cur(dc); 4784 /* fall through */ 4785 case DISAS_EOB_ONLY: 4786 gen_eob(dc); 4787 break; 4788 case DISAS_EOB_INHIBIT_IRQ: 4789 gen_update_cc_op(dc); 4790 gen_update_eip_cur(dc); 4791 gen_eob_inhibit_irq(dc); 4792 break; 4793 case DISAS_JUMP: 4794 gen_jr(dc); 4795 break; 4796 default: 4797 g_assert_not_reached(); 4798 } 4799 } 4800 4801 static void i386_tr_disas_log(const DisasContextBase *dcbase, 4802 CPUState *cpu, FILE *logfile) 4803 { 4804 DisasContext *dc = container_of(dcbase, DisasContext, base); 4805 4806 fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first)); 4807 target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size); 4808 } 4809 4810 static const TranslatorOps i386_tr_ops = { 4811 .init_disas_context = i386_tr_init_disas_context, 4812 .tb_start = i386_tr_tb_start, 4813 .insn_start = i386_tr_insn_start, 4814 .translate_insn = i386_tr_translate_insn, 4815 .tb_stop = i386_tr_tb_stop, 4816 .disas_log = i386_tr_disas_log, 4817 }; 4818 4819 /* generate intermediate code for basic block 'tb'. */ 4820 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns, 4821 vaddr pc, void *host_pc) 4822 { 4823 DisasContext dc; 4824 4825 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); 4826 } 4827