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