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 "exec/translation-block.h" 25 #include "tcg/tcg-op.h" 26 #include "tcg/tcg-op-gvec.h" 27 #include "exec/translator.h" 28 #include "fpu/softfloat.h" 29 30 #include "exec/helper-proto.h" 31 #include "exec/helper-gen.h" 32 #include "helper-tcg.h" 33 #include "decode-new.h" 34 35 #include "exec/log.h" 36 37 #define HELPER_H "helper.h" 38 #include "exec/helper-info.c.inc" 39 #undef HELPER_H 40 41 /* Fixes for Windows namespace pollution. */ 42 #undef IN 43 #undef OUT 44 45 #define PREFIX_REPZ 0x01 46 #define PREFIX_REPNZ 0x02 47 #define PREFIX_LOCK 0x04 48 #define PREFIX_DATA 0x08 49 #define PREFIX_ADR 0x10 50 #define PREFIX_VEX 0x20 51 #define PREFIX_REX 0x40 52 53 #ifdef TARGET_X86_64 54 # define ctztl ctz64 55 # define clztl clz64 56 #else 57 # define ctztl ctz32 58 # define clztl clz32 59 #endif 60 61 /* For a switch indexed by MODRM, match all memory operands for a given OP. */ 62 #define CASE_MODRM_MEM_OP(OP) \ 63 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 64 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 65 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7 66 67 #define CASE_MODRM_OP(OP) \ 68 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 69 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 70 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \ 71 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7 72 73 //#define MACRO_TEST 1 74 75 /* global register indexes */ 76 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2; 77 static TCGv cpu_eip; 78 static TCGv_i32 cpu_cc_op; 79 static TCGv cpu_regs[CPU_NB_REGS]; 80 static TCGv cpu_seg_base[6]; 81 static TCGv_i64 cpu_bndl[4]; 82 static TCGv_i64 cpu_bndu[4]; 83 84 typedef struct DisasContext { 85 DisasContextBase base; 86 87 target_ulong pc; /* pc = eip + cs_base */ 88 target_ulong cs_base; /* base of CS segment */ 89 target_ulong pc_save; 90 91 MemOp aflag; 92 MemOp dflag; 93 94 int8_t override; /* -1 if no override, else R_CS, R_DS, etc */ 95 uint8_t prefix; 96 97 bool has_modrm; 98 uint8_t modrm; 99 100 #ifndef CONFIG_USER_ONLY 101 uint8_t cpl; /* code priv level */ 102 uint8_t iopl; /* i/o priv level */ 103 #endif 104 uint8_t vex_l; /* vex vector length */ 105 uint8_t vex_v; /* vex vvvv register, without 1's complement. */ 106 uint8_t popl_esp_hack; /* for correct popl with esp base handling */ 107 uint8_t rip_offset; /* only used in x86_64, but left for simplicity */ 108 109 #ifdef TARGET_X86_64 110 uint8_t rex_r; 111 uint8_t rex_x; 112 uint8_t rex_b; 113 #endif 114 bool vex_w; /* used by AVX even on 32-bit processors */ 115 bool jmp_opt; /* use direct block chaining for direct jumps */ 116 bool cc_op_dirty; 117 118 CCOp cc_op; /* current CC operation */ 119 int mem_index; /* select memory access functions */ 120 uint32_t flags; /* all execution flags */ 121 int cpuid_features; 122 int cpuid_ext_features; 123 int cpuid_ext2_features; 124 int cpuid_ext3_features; 125 int cpuid_7_0_ebx_features; 126 int cpuid_7_0_ecx_features; 127 int cpuid_7_1_eax_features; 128 int cpuid_xsave_features; 129 130 /* TCG local temps */ 131 TCGv cc_srcT; 132 TCGv A0; 133 TCGv T0; 134 TCGv T1; 135 136 /* TCG local register indexes (only used inside old micro ops) */ 137 TCGv tmp0; 138 TCGv tmp4; 139 TCGv_i32 tmp2_i32; 140 TCGv_i32 tmp3_i32; 141 TCGv_i64 tmp1_i64; 142 143 sigjmp_buf jmpbuf; 144 TCGOp *prev_insn_start; 145 TCGOp *prev_insn_end; 146 } DisasContext; 147 148 /* 149 * Point EIP to next instruction before ending translation. 150 * For instructions that can change hflags. 151 */ 152 #define DISAS_EOB_NEXT DISAS_TARGET_0 153 154 /* 155 * Point EIP to next instruction and set HF_INHIBIT_IRQ if not 156 * already set. For instructions that activate interrupt shadow. 157 */ 158 #define DISAS_EOB_INHIBIT_IRQ DISAS_TARGET_1 159 160 /* 161 * Return to the main loop; EIP might have already been updated 162 * but even in that case do not use lookup_and_goto_ptr(). 163 */ 164 #define DISAS_EOB_ONLY DISAS_TARGET_2 165 166 /* 167 * EIP has already been updated. For jumps that wish to use 168 * lookup_and_goto_ptr() 169 */ 170 #define DISAS_JUMP DISAS_TARGET_3 171 172 /* 173 * EIP has already been updated. Use updated value of 174 * EFLAGS.TF to determine singlestep trap (SYSCALL/SYSRET). 175 */ 176 #define DISAS_EOB_RECHECK_TF DISAS_TARGET_4 177 178 /* The environment in which user-only runs is constrained. */ 179 #ifdef CONFIG_USER_ONLY 180 #define PE(S) true 181 #define CPL(S) 3 182 #define IOPL(S) 0 183 #define SVME(S) false 184 #define GUEST(S) false 185 #else 186 #define PE(S) (((S)->flags & HF_PE_MASK) != 0) 187 #define CPL(S) ((S)->cpl) 188 #define IOPL(S) ((S)->iopl) 189 #define SVME(S) (((S)->flags & HF_SVME_MASK) != 0) 190 #define GUEST(S) (((S)->flags & HF_GUEST_MASK) != 0) 191 #endif 192 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64) 193 #define VM86(S) false 194 #define CODE32(S) true 195 #define SS32(S) true 196 #define ADDSEG(S) false 197 #else 198 #define VM86(S) (((S)->flags & HF_VM_MASK) != 0) 199 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0) 200 #define SS32(S) (((S)->flags & HF_SS32_MASK) != 0) 201 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0) 202 #endif 203 #if !defined(TARGET_X86_64) 204 #define CODE64(S) false 205 #elif defined(CONFIG_USER_ONLY) 206 #define CODE64(S) true 207 #else 208 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0) 209 #endif 210 #if defined(CONFIG_USER_ONLY) || defined(TARGET_X86_64) 211 #define LMA(S) (((S)->flags & HF_LMA_MASK) != 0) 212 #else 213 #define LMA(S) false 214 #endif 215 216 #ifdef TARGET_X86_64 217 #define REX_PREFIX(S) (((S)->prefix & PREFIX_REX) != 0) 218 #define REX_W(S) ((S)->vex_w) 219 #define REX_R(S) ((S)->rex_r + 0) 220 #define REX_X(S) ((S)->rex_x + 0) 221 #define REX_B(S) ((S)->rex_b + 0) 222 #else 223 #define REX_PREFIX(S) false 224 #define REX_W(S) false 225 #define REX_R(S) 0 226 #define REX_X(S) 0 227 #define REX_B(S) 0 228 #endif 229 230 /* 231 * Many system-only helpers are not reachable for user-only. 232 * Define stub generators here, so that we need not either sprinkle 233 * ifdefs through the translator, nor provide the helper function. 234 */ 235 #define STUB_HELPER(NAME, ...) \ 236 static inline void gen_helper_##NAME(__VA_ARGS__) \ 237 { qemu_build_not_reached(); } 238 239 #ifdef CONFIG_USER_ONLY 240 STUB_HELPER(clgi, TCGv_env env) 241 STUB_HELPER(flush_page, TCGv_env env, TCGv addr) 242 STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port) 243 STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port) 244 STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port) 245 STUB_HELPER(monitor, TCGv_env env, TCGv addr) 246 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs) 247 STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 248 STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 249 STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 250 STUB_HELPER(stgi, TCGv_env env) 251 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type) 252 STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag) 253 STUB_HELPER(vmmcall, TCGv_env env) 254 STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs) 255 STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag) 256 STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val) 257 #endif 258 259 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num); 260 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num); 261 static void gen_exception_gpf(DisasContext *s); 262 263 /* i386 shift ops */ 264 enum { 265 OP_ROL, 266 OP_ROR, 267 OP_RCL, 268 OP_RCR, 269 OP_SHL, 270 OP_SHR, 271 OP_SHL1, /* undocumented */ 272 OP_SAR = 7, 273 }; 274 275 enum { 276 JCC_O, 277 JCC_B, 278 JCC_Z, 279 JCC_BE, 280 JCC_S, 281 JCC_P, 282 JCC_L, 283 JCC_LE, 284 }; 285 286 enum { 287 USES_CC_DST = 1, 288 USES_CC_SRC = 2, 289 USES_CC_SRC2 = 4, 290 USES_CC_SRCT = 8, 291 }; 292 293 /* Bit set if the global variable is live after setting CC_OP to X. */ 294 static const uint8_t cc_op_live_[] = { 295 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 296 [CC_OP_EFLAGS] = USES_CC_SRC, 297 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC, 298 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC, 299 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 300 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT, 301 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 302 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST, 303 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC, 304 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC, 305 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC, 306 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC, 307 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC, 308 [CC_OP_BLSIB ... CC_OP_BLSIQ] = USES_CC_DST | USES_CC_SRC, 309 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC, 310 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2, 311 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 312 [CC_OP_POPCNT] = USES_CC_DST, 313 }; 314 315 static uint8_t cc_op_live(CCOp op) 316 { 317 uint8_t result; 318 assert(op >= 0 && op < ARRAY_SIZE(cc_op_live_)); 319 320 /* 321 * Check that the array is fully populated. A zero entry would correspond 322 * to a fixed value of EFLAGS, which can be obtained with CC_OP_EFLAGS 323 * as well. 324 */ 325 result = cc_op_live_[op]; 326 assert(result); 327 return result; 328 } 329 330 static void set_cc_op_1(DisasContext *s, CCOp op, bool dirty) 331 { 332 int dead; 333 334 if (s->cc_op == op) { 335 return; 336 } 337 338 /* Discard CC computation that will no longer be used. */ 339 dead = cc_op_live(s->cc_op) & ~cc_op_live(op); 340 if (dead & USES_CC_DST) { 341 tcg_gen_discard_tl(cpu_cc_dst); 342 } 343 if (dead & USES_CC_SRC) { 344 tcg_gen_discard_tl(cpu_cc_src); 345 } 346 if (dead & USES_CC_SRC2) { 347 tcg_gen_discard_tl(cpu_cc_src2); 348 } 349 if (dead & USES_CC_SRCT) { 350 tcg_gen_discard_tl(s->cc_srcT); 351 } 352 353 if (dirty && s->cc_op == CC_OP_DYNAMIC) { 354 tcg_gen_discard_i32(cpu_cc_op); 355 } 356 s->cc_op_dirty = dirty; 357 s->cc_op = op; 358 } 359 360 static void set_cc_op(DisasContext *s, CCOp op) 361 { 362 /* 363 * The DYNAMIC setting is translator only, everything else 364 * will be spilled later. 365 */ 366 set_cc_op_1(s, op, op != CC_OP_DYNAMIC); 367 } 368 369 static void assume_cc_op(DisasContext *s, CCOp op) 370 { 371 set_cc_op_1(s, op, false); 372 } 373 374 static void gen_update_cc_op(DisasContext *s) 375 { 376 if (s->cc_op_dirty) { 377 tcg_gen_movi_i32(cpu_cc_op, s->cc_op); 378 s->cc_op_dirty = false; 379 } 380 } 381 382 #ifdef TARGET_X86_64 383 384 #define NB_OP_SIZES 4 385 386 #else /* !TARGET_X86_64 */ 387 388 #define NB_OP_SIZES 3 389 390 #endif /* !TARGET_X86_64 */ 391 392 #if HOST_BIG_ENDIAN 393 #define REG_B_OFFSET (sizeof(target_ulong) - 1) 394 #define REG_H_OFFSET (sizeof(target_ulong) - 2) 395 #define REG_W_OFFSET (sizeof(target_ulong) - 2) 396 #define REG_L_OFFSET (sizeof(target_ulong) - 4) 397 #define REG_LH_OFFSET (sizeof(target_ulong) - 8) 398 #else 399 #define REG_B_OFFSET 0 400 #define REG_H_OFFSET 1 401 #define REG_W_OFFSET 0 402 #define REG_L_OFFSET 0 403 #define REG_LH_OFFSET 4 404 #endif 405 406 /* In instruction encodings for byte register accesses the 407 * register number usually indicates "low 8 bits of register N"; 408 * however there are some special cases where N 4..7 indicates 409 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return 410 * true for this special case, false otherwise. 411 */ 412 static inline bool byte_reg_is_xH(DisasContext *s, int reg) 413 { 414 /* Any time the REX prefix is present, byte registers are uniform */ 415 if (reg < 4 || REX_PREFIX(s)) { 416 return false; 417 } 418 return true; 419 } 420 421 /* Select the size of a push/pop operation. */ 422 static inline MemOp mo_pushpop(DisasContext *s, MemOp ot) 423 { 424 if (CODE64(s)) { 425 return ot == MO_16 ? MO_16 : MO_64; 426 } else { 427 return ot; 428 } 429 } 430 431 /* Select the size of the stack pointer. */ 432 static inline MemOp mo_stacksize(DisasContext *s) 433 { 434 return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16; 435 } 436 437 /* Compute the result of writing t0 to the OT-sized register REG. 438 * 439 * If DEST is NULL, store the result into the register and return the 440 * register's TCGv. 441 * 442 * If DEST is not NULL, store the result into DEST and return the 443 * register's TCGv. 444 */ 445 static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest, TCGv t0) 446 { 447 switch(ot) { 448 case MO_8: 449 if (byte_reg_is_xH(s, reg)) { 450 dest = dest ? dest : cpu_regs[reg - 4]; 451 tcg_gen_deposit_tl(dest, cpu_regs[reg - 4], t0, 8, 8); 452 return cpu_regs[reg - 4]; 453 } 454 dest = dest ? dest : cpu_regs[reg]; 455 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 8); 456 break; 457 case MO_16: 458 dest = dest ? dest : cpu_regs[reg]; 459 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 16); 460 break; 461 case MO_32: 462 /* For x86_64, this sets the higher half of register to zero. 463 For i386, this is equivalent to a mov. */ 464 dest = dest ? dest : cpu_regs[reg]; 465 tcg_gen_ext32u_tl(dest, t0); 466 break; 467 #ifdef TARGET_X86_64 468 case MO_64: 469 dest = dest ? dest : cpu_regs[reg]; 470 tcg_gen_mov_tl(dest, t0); 471 break; 472 #endif 473 default: 474 g_assert_not_reached(); 475 } 476 return cpu_regs[reg]; 477 } 478 479 static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0) 480 { 481 gen_op_deposit_reg_v(s, ot, reg, NULL, t0); 482 } 483 484 static inline 485 void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg) 486 { 487 if (ot == MO_8 && byte_reg_is_xH(s, reg)) { 488 tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8); 489 } else { 490 tcg_gen_mov_tl(t0, cpu_regs[reg]); 491 } 492 } 493 494 static void gen_add_A0_im(DisasContext *s, int val) 495 { 496 tcg_gen_addi_tl(s->A0, s->A0, val); 497 if (!CODE64(s)) { 498 tcg_gen_ext32u_tl(s->A0, s->A0); 499 } 500 } 501 502 static inline void gen_op_jmp_v(DisasContext *s, TCGv dest) 503 { 504 tcg_gen_mov_tl(cpu_eip, dest); 505 s->pc_save = -1; 506 } 507 508 static inline 509 void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val) 510 { 511 tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val); 512 gen_op_mov_reg_v(s, size, reg, s->tmp0); 513 } 514 515 static inline void gen_op_add_reg(DisasContext *s, MemOp size, int reg, TCGv val) 516 { 517 tcg_gen_add_tl(s->tmp0, cpu_regs[reg], val); 518 gen_op_mov_reg_v(s, size, reg, s->tmp0); 519 } 520 521 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 522 { 523 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE); 524 } 525 526 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 527 { 528 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE); 529 } 530 531 static void gen_update_eip_next(DisasContext *s) 532 { 533 assert(s->pc_save != -1); 534 if (tb_cflags(s->base.tb) & CF_PCREL) { 535 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save); 536 } else if (CODE64(s)) { 537 tcg_gen_movi_tl(cpu_eip, s->pc); 538 } else { 539 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->pc - s->cs_base)); 540 } 541 s->pc_save = s->pc; 542 } 543 544 static void gen_update_eip_cur(DisasContext *s) 545 { 546 assert(s->pc_save != -1); 547 if (tb_cflags(s->base.tb) & CF_PCREL) { 548 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save); 549 } else if (CODE64(s)) { 550 tcg_gen_movi_tl(cpu_eip, s->base.pc_next); 551 } else { 552 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->base.pc_next - s->cs_base)); 553 } 554 s->pc_save = s->base.pc_next; 555 } 556 557 static int cur_insn_len(DisasContext *s) 558 { 559 return s->pc - s->base.pc_next; 560 } 561 562 static TCGv_i32 cur_insn_len_i32(DisasContext *s) 563 { 564 return tcg_constant_i32(cur_insn_len(s)); 565 } 566 567 static TCGv_i32 eip_next_i32(DisasContext *s) 568 { 569 assert(s->pc_save != -1); 570 /* 571 * This function has two users: lcall_real (always 16-bit mode), and 572 * iret_protected (16, 32, or 64-bit mode). IRET only uses the value 573 * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is 574 * why passing a 32-bit value isn't broken. To avoid using this where 575 * we shouldn't, return -1 in 64-bit mode so that execution goes into 576 * the weeds quickly. 577 */ 578 if (CODE64(s)) { 579 return tcg_constant_i32(-1); 580 } 581 if (tb_cflags(s->base.tb) & CF_PCREL) { 582 TCGv_i32 ret = tcg_temp_new_i32(); 583 tcg_gen_trunc_tl_i32(ret, cpu_eip); 584 tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save); 585 return ret; 586 } else { 587 return tcg_constant_i32(s->pc - s->cs_base); 588 } 589 } 590 591 static TCGv eip_next_tl(DisasContext *s) 592 { 593 assert(s->pc_save != -1); 594 if (tb_cflags(s->base.tb) & CF_PCREL) { 595 TCGv ret = tcg_temp_new(); 596 tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save); 597 return ret; 598 } else if (CODE64(s)) { 599 return tcg_constant_tl(s->pc); 600 } else { 601 return tcg_constant_tl((uint32_t)(s->pc - s->cs_base)); 602 } 603 } 604 605 static TCGv eip_cur_tl(DisasContext *s) 606 { 607 assert(s->pc_save != -1); 608 if (tb_cflags(s->base.tb) & CF_PCREL) { 609 TCGv ret = tcg_temp_new(); 610 tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save); 611 return ret; 612 } else if (CODE64(s)) { 613 return tcg_constant_tl(s->base.pc_next); 614 } else { 615 return tcg_constant_tl((uint32_t)(s->base.pc_next - s->cs_base)); 616 } 617 } 618 619 /* Compute SEG:REG into DEST. SEG is selected from the override segment 620 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to 621 indicate no override. */ 622 static void gen_lea_v_seg_dest(DisasContext *s, MemOp aflag, TCGv dest, TCGv a0, 623 int def_seg, int ovr_seg) 624 { 625 switch (aflag) { 626 #ifdef TARGET_X86_64 627 case MO_64: 628 if (ovr_seg < 0) { 629 tcg_gen_mov_tl(dest, a0); 630 return; 631 } 632 break; 633 #endif 634 case MO_32: 635 /* 32 bit address */ 636 if (ovr_seg < 0 && ADDSEG(s)) { 637 ovr_seg = def_seg; 638 } 639 if (ovr_seg < 0) { 640 tcg_gen_ext32u_tl(dest, a0); 641 return; 642 } 643 break; 644 case MO_16: 645 /* 16 bit address */ 646 tcg_gen_ext16u_tl(dest, a0); 647 a0 = dest; 648 if (ovr_seg < 0) { 649 if (ADDSEG(s)) { 650 ovr_seg = def_seg; 651 } else { 652 return; 653 } 654 } 655 break; 656 default: 657 g_assert_not_reached(); 658 } 659 660 if (ovr_seg >= 0) { 661 TCGv seg = cpu_seg_base[ovr_seg]; 662 663 if (aflag == MO_64) { 664 tcg_gen_add_tl(dest, a0, seg); 665 } else if (CODE64(s)) { 666 tcg_gen_ext32u_tl(dest, a0); 667 tcg_gen_add_tl(dest, dest, seg); 668 } else { 669 tcg_gen_add_tl(dest, a0, seg); 670 tcg_gen_ext32u_tl(dest, dest); 671 } 672 } 673 } 674 675 static void gen_lea_v_seg(DisasContext *s, TCGv a0, 676 int def_seg, int ovr_seg) 677 { 678 gen_lea_v_seg_dest(s, s->aflag, s->A0, a0, def_seg, ovr_seg); 679 } 680 681 static inline void gen_string_movl_A0_ESI(DisasContext *s) 682 { 683 gen_lea_v_seg(s, cpu_regs[R_ESI], R_DS, s->override); 684 } 685 686 static inline void gen_string_movl_A0_EDI(DisasContext *s) 687 { 688 gen_lea_v_seg(s, cpu_regs[R_EDI], R_ES, -1); 689 } 690 691 static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign) 692 { 693 if (size == MO_TL) { 694 return src; 695 } 696 if (!dst) { 697 dst = tcg_temp_new(); 698 } 699 tcg_gen_ext_tl(dst, src, size | (sign ? MO_SIGN : 0)); 700 return dst; 701 } 702 703 static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1) 704 { 705 TCGv tmp = gen_ext_tl(NULL, cpu_regs[R_ECX], s->aflag, false); 706 707 tcg_gen_brcondi_tl(cond, tmp, 0, label1); 708 } 709 710 static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1) 711 { 712 gen_op_j_ecx(s, TCG_COND_EQ, label1); 713 } 714 715 static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1) 716 { 717 gen_op_j_ecx(s, TCG_COND_NE, label1); 718 } 719 720 static void gen_set_hflag(DisasContext *s, uint32_t mask) 721 { 722 if ((s->flags & mask) == 0) { 723 TCGv_i32 t = tcg_temp_new_i32(); 724 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 725 tcg_gen_ori_i32(t, t, mask); 726 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 727 s->flags |= mask; 728 } 729 } 730 731 static void gen_reset_hflag(DisasContext *s, uint32_t mask) 732 { 733 if (s->flags & mask) { 734 TCGv_i32 t = tcg_temp_new_i32(); 735 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 736 tcg_gen_andi_i32(t, t, ~mask); 737 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 738 s->flags &= ~mask; 739 } 740 } 741 742 static void gen_set_eflags(DisasContext *s, target_ulong mask) 743 { 744 TCGv t = tcg_temp_new(); 745 746 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 747 tcg_gen_ori_tl(t, t, mask); 748 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 749 } 750 751 static void gen_reset_eflags(DisasContext *s, target_ulong mask) 752 { 753 TCGv t = tcg_temp_new(); 754 755 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 756 tcg_gen_andi_tl(t, t, ~mask); 757 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 758 } 759 760 static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n) 761 { 762 switch (ot) { 763 case MO_8: 764 gen_helper_inb(v, tcg_env, n); 765 break; 766 case MO_16: 767 gen_helper_inw(v, tcg_env, n); 768 break; 769 case MO_32: 770 gen_helper_inl(v, tcg_env, n); 771 break; 772 default: 773 g_assert_not_reached(); 774 } 775 } 776 777 static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n) 778 { 779 switch (ot) { 780 case MO_8: 781 gen_helper_outb(tcg_env, v, n); 782 break; 783 case MO_16: 784 gen_helper_outw(tcg_env, v, n); 785 break; 786 case MO_32: 787 gen_helper_outl(tcg_env, v, n); 788 break; 789 default: 790 g_assert_not_reached(); 791 } 792 } 793 794 /* 795 * Validate that access to [port, port + 1<<ot) is allowed. 796 * Raise #GP, or VMM exit if not. 797 */ 798 static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port, 799 uint32_t svm_flags) 800 { 801 #ifdef CONFIG_USER_ONLY 802 /* 803 * We do not implement the ioperm(2) syscall, so the TSS check 804 * will always fail. 805 */ 806 gen_exception_gpf(s); 807 return false; 808 #else 809 if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) { 810 gen_helper_check_io(tcg_env, port, tcg_constant_i32(1 << ot)); 811 } 812 if (GUEST(s)) { 813 gen_update_cc_op(s); 814 gen_update_eip_cur(s); 815 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) { 816 svm_flags |= SVM_IOIO_REP_MASK; 817 } 818 svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot); 819 gen_helper_svm_check_io(tcg_env, port, 820 tcg_constant_i32(svm_flags), 821 cur_insn_len_i32(s)); 822 } 823 return true; 824 #endif 825 } 826 827 static void gen_movs(DisasContext *s, MemOp ot, TCGv dshift) 828 { 829 gen_string_movl_A0_ESI(s); 830 gen_op_ld_v(s, ot, s->T0, s->A0); 831 gen_string_movl_A0_EDI(s); 832 gen_op_st_v(s, ot, s->T0, s->A0); 833 834 gen_op_add_reg(s, s->aflag, R_ESI, dshift); 835 gen_op_add_reg(s, s->aflag, R_EDI, dshift); 836 } 837 838 /* compute all eflags to reg */ 839 static void gen_mov_eflags(DisasContext *s, TCGv reg) 840 { 841 TCGv dst, src1, src2; 842 TCGv_i32 cc_op; 843 int live, dead; 844 845 if (s->cc_op == CC_OP_EFLAGS) { 846 tcg_gen_mov_tl(reg, cpu_cc_src); 847 return; 848 } 849 850 dst = cpu_cc_dst; 851 src1 = cpu_cc_src; 852 src2 = cpu_cc_src2; 853 854 /* Take care to not read values that are not live. */ 855 live = cc_op_live(s->cc_op) & ~USES_CC_SRCT; 856 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2); 857 if (dead) { 858 TCGv zero = tcg_constant_tl(0); 859 if (dead & USES_CC_DST) { 860 dst = zero; 861 } 862 if (dead & USES_CC_SRC) { 863 src1 = zero; 864 } 865 if (dead & USES_CC_SRC2) { 866 src2 = zero; 867 } 868 } 869 870 if (s->cc_op != CC_OP_DYNAMIC) { 871 cc_op = tcg_constant_i32(s->cc_op); 872 } else { 873 cc_op = cpu_cc_op; 874 } 875 gen_helper_cc_compute_all(reg, dst, src1, src2, cc_op); 876 } 877 878 /* compute all eflags to cc_src */ 879 static void gen_compute_eflags(DisasContext *s) 880 { 881 gen_mov_eflags(s, cpu_cc_src); 882 set_cc_op(s, CC_OP_EFLAGS); 883 } 884 885 typedef struct CCPrepare { 886 TCGCond cond; 887 TCGv reg; 888 TCGv reg2; 889 target_ulong imm; 890 bool use_reg2; 891 bool no_setcond; 892 } CCPrepare; 893 894 static CCPrepare gen_prepare_sign_nz(TCGv src, MemOp size) 895 { 896 if (size == MO_TL) { 897 return (CCPrepare) { .cond = TCG_COND_LT, .reg = src }; 898 } else { 899 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = src, 900 .imm = 1ull << ((8 << size) - 1) }; 901 } 902 } 903 904 static CCPrepare gen_prepare_val_nz(TCGv src, MemOp size, bool eqz) 905 { 906 if (size == MO_TL) { 907 return (CCPrepare) { .cond = eqz ? TCG_COND_EQ : TCG_COND_NE, 908 .reg = src }; 909 } else { 910 return (CCPrepare) { .cond = eqz ? TCG_COND_TSTEQ : TCG_COND_TSTNE, 911 .imm = MAKE_64BIT_MASK(0, 8 << size), 912 .reg = src }; 913 } 914 } 915 916 /* compute eflags.C, trying to store it in reg if not NULL */ 917 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg) 918 { 919 MemOp size; 920 921 switch (s->cc_op) { 922 case CC_OP_SUBB ... CC_OP_SUBQ: 923 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */ 924 size = s->cc_op - CC_OP_SUBB; 925 tcg_gen_ext_tl(s->cc_srcT, s->cc_srcT, size); 926 tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size); 927 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = s->cc_srcT, 928 .reg2 = cpu_cc_src, .use_reg2 = true }; 929 930 case CC_OP_ADDB ... CC_OP_ADDQ: 931 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */ 932 size = cc_op_size(s->cc_op); 933 tcg_gen_ext_tl(cpu_cc_dst, cpu_cc_dst, size); 934 tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size); 935 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = cpu_cc_dst, 936 .reg2 = cpu_cc_src, .use_reg2 = true }; 937 938 case CC_OP_LOGICB ... CC_OP_LOGICQ: 939 case CC_OP_POPCNT: 940 return (CCPrepare) { .cond = TCG_COND_NEVER }; 941 942 case CC_OP_INCB ... CC_OP_INCQ: 943 case CC_OP_DECB ... CC_OP_DECQ: 944 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 945 .no_setcond = true }; 946 947 case CC_OP_SHLB ... CC_OP_SHLQ: 948 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */ 949 size = cc_op_size(s->cc_op); 950 return gen_prepare_sign_nz(cpu_cc_src, size); 951 952 case CC_OP_MULB ... CC_OP_MULQ: 953 return (CCPrepare) { .cond = TCG_COND_NE, 954 .reg = cpu_cc_src }; 955 956 case CC_OP_BMILGB ... CC_OP_BMILGQ: 957 size = cc_op_size(s->cc_op); 958 return gen_prepare_val_nz(cpu_cc_src, size, true); 959 960 case CC_OP_BLSIB ... CC_OP_BLSIQ: 961 size = cc_op_size(s->cc_op); 962 return gen_prepare_val_nz(cpu_cc_src, size, false); 963 964 case CC_OP_ADCX: 965 case CC_OP_ADCOX: 966 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst, 967 .no_setcond = true }; 968 969 case CC_OP_EFLAGS: 970 case CC_OP_SARB ... CC_OP_SARQ: 971 /* CC_SRC & 1 */ 972 return (CCPrepare) { .cond = TCG_COND_TSTNE, 973 .reg = cpu_cc_src, .imm = CC_C }; 974 975 default: 976 /* The need to compute only C from CC_OP_DYNAMIC is important 977 in efficiently implementing e.g. INC at the start of a TB. */ 978 gen_update_cc_op(s); 979 if (!reg) { 980 reg = tcg_temp_new(); 981 } 982 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src, 983 cpu_cc_src2, cpu_cc_op); 984 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg, 985 .no_setcond = true }; 986 } 987 } 988 989 /* compute eflags.P, trying to store it in reg if not NULL */ 990 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg) 991 { 992 gen_compute_eflags(s); 993 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 994 .imm = CC_P }; 995 } 996 997 /* compute eflags.S, trying to store it in reg if not NULL */ 998 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg) 999 { 1000 switch (s->cc_op) { 1001 case CC_OP_DYNAMIC: 1002 gen_compute_eflags(s); 1003 /* FALLTHRU */ 1004 case CC_OP_EFLAGS: 1005 case CC_OP_ADCX: 1006 case CC_OP_ADOX: 1007 case CC_OP_ADCOX: 1008 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1009 .imm = CC_S }; 1010 case CC_OP_POPCNT: 1011 return (CCPrepare) { .cond = TCG_COND_NEVER }; 1012 default: 1013 return gen_prepare_sign_nz(cpu_cc_dst, cc_op_size(s->cc_op)); 1014 } 1015 } 1016 1017 /* compute eflags.O, trying to store it in reg if not NULL */ 1018 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg) 1019 { 1020 switch (s->cc_op) { 1021 case CC_OP_ADOX: 1022 case CC_OP_ADCOX: 1023 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2, 1024 .no_setcond = true }; 1025 case CC_OP_LOGICB ... CC_OP_LOGICQ: 1026 case CC_OP_POPCNT: 1027 return (CCPrepare) { .cond = TCG_COND_NEVER }; 1028 case CC_OP_MULB ... CC_OP_MULQ: 1029 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src }; 1030 default: 1031 gen_compute_eflags(s); 1032 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1033 .imm = CC_O }; 1034 } 1035 } 1036 1037 /* compute eflags.Z, trying to store it in reg if not NULL */ 1038 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg) 1039 { 1040 switch (s->cc_op) { 1041 case CC_OP_EFLAGS: 1042 case CC_OP_ADCX: 1043 case CC_OP_ADOX: 1044 case CC_OP_ADCOX: 1045 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1046 .imm = CC_Z }; 1047 case CC_OP_DYNAMIC: 1048 gen_update_cc_op(s); 1049 if (!reg) { 1050 reg = tcg_temp_new(); 1051 } 1052 gen_helper_cc_compute_nz(reg, cpu_cc_dst, cpu_cc_src, cpu_cc_op); 1053 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = reg, .imm = 0 }; 1054 case CC_OP_POPCNT: 1055 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_dst }; 1056 default: 1057 { 1058 MemOp size = cc_op_size(s->cc_op); 1059 return gen_prepare_val_nz(cpu_cc_dst, size, true); 1060 } 1061 } 1062 } 1063 1064 /* return how to compute jump opcode 'b'. 'reg' can be clobbered 1065 * if needed; it may be used for CCPrepare.reg if that will 1066 * provide more freedom in the translation of a subsequent setcond. */ 1067 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg) 1068 { 1069 int inv, jcc_op, cond; 1070 MemOp size; 1071 CCPrepare cc; 1072 1073 inv = b & 1; 1074 jcc_op = (b >> 1) & 7; 1075 1076 switch (s->cc_op) { 1077 case CC_OP_SUBB ... CC_OP_SUBQ: 1078 /* We optimize relational operators for the cmp/jcc case. */ 1079 size = cc_op_size(s->cc_op); 1080 switch (jcc_op) { 1081 case JCC_BE: 1082 tcg_gen_ext_tl(s->cc_srcT, s->cc_srcT, size); 1083 tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size); 1084 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->cc_srcT, 1085 .reg2 = cpu_cc_src, .use_reg2 = true }; 1086 break; 1087 case JCC_L: 1088 cond = TCG_COND_LT; 1089 goto fast_jcc_l; 1090 case JCC_LE: 1091 cond = TCG_COND_LE; 1092 fast_jcc_l: 1093 tcg_gen_ext_tl(s->cc_srcT, s->cc_srcT, size | MO_SIGN); 1094 tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size | MO_SIGN); 1095 cc = (CCPrepare) { .cond = cond, .reg = s->cc_srcT, 1096 .reg2 = cpu_cc_src, .use_reg2 = true }; 1097 break; 1098 1099 default: 1100 goto slow_jcc; 1101 } 1102 break; 1103 1104 case CC_OP_LOGICB ... CC_OP_LOGICQ: 1105 /* Mostly used for test+jump */ 1106 size = s->cc_op - CC_OP_LOGICB; 1107 switch (jcc_op) { 1108 case JCC_BE: 1109 /* CF = 0, becomes jz/je */ 1110 jcc_op = JCC_Z; 1111 goto slow_jcc; 1112 case JCC_L: 1113 /* OF = 0, becomes js/jns */ 1114 jcc_op = JCC_S; 1115 goto slow_jcc; 1116 case JCC_LE: 1117 /* SF or ZF, becomes signed <= 0 */ 1118 tcg_gen_ext_tl(cpu_cc_dst, cpu_cc_dst, size | MO_SIGN); 1119 cc = (CCPrepare) { .cond = TCG_COND_LE, .reg = cpu_cc_dst }; 1120 break; 1121 default: 1122 goto slow_jcc; 1123 } 1124 break; 1125 1126 default: 1127 slow_jcc: 1128 /* This actually generates good code for JC, JZ and JS. */ 1129 switch (jcc_op) { 1130 case JCC_O: 1131 cc = gen_prepare_eflags_o(s, reg); 1132 break; 1133 case JCC_B: 1134 cc = gen_prepare_eflags_c(s, reg); 1135 break; 1136 case JCC_Z: 1137 cc = gen_prepare_eflags_z(s, reg); 1138 break; 1139 case JCC_BE: 1140 gen_compute_eflags(s); 1141 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1142 .imm = CC_Z | CC_C }; 1143 break; 1144 case JCC_S: 1145 cc = gen_prepare_eflags_s(s, reg); 1146 break; 1147 case JCC_P: 1148 cc = gen_prepare_eflags_p(s, reg); 1149 break; 1150 case JCC_L: 1151 gen_compute_eflags(s); 1152 if (!reg || reg == cpu_cc_src) { 1153 reg = tcg_temp_new(); 1154 } 1155 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S); 1156 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg, 1157 .imm = CC_O }; 1158 break; 1159 default: 1160 case JCC_LE: 1161 gen_compute_eflags(s); 1162 if (!reg || reg == cpu_cc_src) { 1163 reg = tcg_temp_new(); 1164 } 1165 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S); 1166 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg, 1167 .imm = CC_O | CC_Z }; 1168 break; 1169 } 1170 break; 1171 } 1172 1173 if (inv) { 1174 cc.cond = tcg_invert_cond(cc.cond); 1175 } 1176 return cc; 1177 } 1178 1179 static void gen_setcc(DisasContext *s, int b, TCGv reg) 1180 { 1181 CCPrepare cc = gen_prepare_cc(s, b, reg); 1182 1183 if (cc.no_setcond) { 1184 if (cc.cond == TCG_COND_EQ) { 1185 tcg_gen_xori_tl(reg, cc.reg, 1); 1186 } else { 1187 tcg_gen_mov_tl(reg, cc.reg); 1188 } 1189 return; 1190 } 1191 1192 if (cc.use_reg2) { 1193 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2); 1194 } else { 1195 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm); 1196 } 1197 } 1198 1199 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg) 1200 { 1201 gen_setcc(s, JCC_B << 1, reg); 1202 } 1203 1204 /* generate a conditional jump to label 'l1' according to jump opcode 1205 value 'b'. In the fast case, T0 is guaranteed not to be used. */ 1206 static inline void gen_jcc_noeob(DisasContext *s, int b, TCGLabel *l1) 1207 { 1208 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1209 1210 if (cc.use_reg2) { 1211 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1212 } else { 1213 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1214 } 1215 } 1216 1217 /* Generate a conditional jump to label 'l1' according to jump opcode 1218 value 'b'. In the fast case, T0 is guaranteed not to be used. 1219 One or both of the branches will call gen_jmp_rel, so ensure 1220 cc_op is clean. */ 1221 static inline void gen_jcc(DisasContext *s, int b, TCGLabel *l1) 1222 { 1223 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1224 1225 /* 1226 * Note that this must be _after_ gen_prepare_cc, because it can change 1227 * the cc_op to CC_OP_EFLAGS (because it's CC_OP_DYNAMIC or because 1228 * it's cheaper to just compute the flags)! 1229 */ 1230 gen_update_cc_op(s); 1231 if (cc.use_reg2) { 1232 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1233 } else { 1234 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1235 } 1236 } 1237 1238 static void gen_stos(DisasContext *s, MemOp ot, TCGv dshift) 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, dshift); 1243 } 1244 1245 static void gen_lods(DisasContext *s, MemOp ot, TCGv dshift) 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, dshift); 1251 } 1252 1253 static void gen_scas(DisasContext *s, MemOp ot, TCGv dshift) 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, dshift); 1263 } 1264 1265 static void gen_cmps(DisasContext *s, MemOp ot, TCGv dshift) 1266 { 1267 gen_string_movl_A0_EDI(s); 1268 gen_op_ld_v(s, ot, s->T1, s->A0); 1269 gen_string_movl_A0_ESI(s); 1270 gen_op_ld_v(s, ot, s->T0, s->A0); 1271 tcg_gen_mov_tl(cpu_cc_src, s->T1); 1272 tcg_gen_mov_tl(s->cc_srcT, s->T0); 1273 tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1); 1274 set_cc_op(s, CC_OP_SUBB + ot); 1275 1276 gen_op_add_reg(s, s->aflag, R_ESI, dshift); 1277 gen_op_add_reg(s, s->aflag, R_EDI, dshift); 1278 } 1279 1280 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot) 1281 { 1282 if (s->flags & HF_IOBPT_MASK) { 1283 #ifdef CONFIG_USER_ONLY 1284 /* user-mode cpu should not be in IOBPT mode */ 1285 g_assert_not_reached(); 1286 #else 1287 TCGv_i32 t_size = tcg_constant_i32(1 << ot); 1288 TCGv t_next = eip_next_tl(s); 1289 gen_helper_bpt_io(tcg_env, t_port, t_size, t_next); 1290 #endif /* CONFIG_USER_ONLY */ 1291 } 1292 } 1293 1294 static void gen_ins(DisasContext *s, MemOp ot, TCGv dshift) 1295 { 1296 gen_string_movl_A0_EDI(s); 1297 /* Note: we must do this dummy write first to be restartable in 1298 case of page fault. */ 1299 tcg_gen_movi_tl(s->T0, 0); 1300 gen_op_st_v(s, ot, s->T0, s->A0); 1301 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 1302 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); 1303 gen_helper_in_func(ot, s->T0, s->tmp2_i32); 1304 gen_op_st_v(s, ot, s->T0, s->A0); 1305 gen_op_add_reg(s, s->aflag, R_EDI, dshift); 1306 gen_bpt_io(s, s->tmp2_i32, ot); 1307 } 1308 1309 static void gen_outs(DisasContext *s, MemOp ot, TCGv dshift) 1310 { 1311 gen_string_movl_A0_ESI(s); 1312 gen_op_ld_v(s, ot, s->T0, s->A0); 1313 1314 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 1315 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); 1316 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0); 1317 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 1318 gen_op_add_reg(s, s->aflag, R_ESI, dshift); 1319 gen_bpt_io(s, s->tmp2_i32, ot); 1320 } 1321 1322 #define REP_MAX 65535 1323 1324 static void do_gen_rep(DisasContext *s, MemOp ot, TCGv dshift, 1325 void (*fn)(DisasContext *s, MemOp ot, TCGv dshift), 1326 bool is_repz_nz) 1327 { 1328 TCGLabel *last = gen_new_label(); 1329 TCGLabel *loop = gen_new_label(); 1330 TCGLabel *done = gen_new_label(); 1331 1332 target_ulong cx_mask = MAKE_64BIT_MASK(0, 8 << s->aflag); 1333 TCGv cx_next = tcg_temp_new(); 1334 1335 /* 1336 * Check if we must translate a single iteration only. Normally, HF_RF_MASK 1337 * would also limit translation blocks to one instruction, so that gen_eob 1338 * can reset the flag; here however RF is set throughout the repetition, so 1339 * we can plow through until CX/ECX/RCX is zero. 1340 */ 1341 bool can_loop = 1342 (!(tb_cflags(s->base.tb) & (CF_USE_ICOUNT | CF_SINGLE_STEP)) 1343 && !(s->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 1344 bool had_rf = s->flags & HF_RF_MASK; 1345 1346 /* 1347 * Even if EFLAGS.RF was set on entry (such as if we're on the second or 1348 * later iteration and an exception or interrupt happened), force gen_eob() 1349 * not to clear the flag. We do that ourselves after the last iteration. 1350 */ 1351 s->flags &= ~HF_RF_MASK; 1352 1353 /* 1354 * For CMPS/SCAS, the CC_OP after a memory fault could come from either 1355 * the previous instruction or the string instruction; but because we 1356 * arrange to keep CC_OP up to date all the time, just mark the whole 1357 * insn as CC_OP_DYNAMIC. 1358 * 1359 * It's not a problem to do this even for instructions that do not 1360 * modify the flags, so do it unconditionally. 1361 */ 1362 gen_update_cc_op(s); 1363 tcg_set_insn_start_param(s->base.insn_start, 1, CC_OP_DYNAMIC); 1364 1365 /* Any iteration at all? */ 1366 tcg_gen_brcondi_tl(TCG_COND_TSTEQ, cpu_regs[R_ECX], cx_mask, done); 1367 1368 /* 1369 * From now on we operate on the value of CX/ECX/RCX that will be written 1370 * back, which is stored in cx_next. There can be no carry, so we can zero 1371 * extend here if needed and not do any expensive deposit operations later. 1372 */ 1373 tcg_gen_subi_tl(cx_next, cpu_regs[R_ECX], 1); 1374 #ifdef TARGET_X86_64 1375 if (s->aflag == MO_32) { 1376 tcg_gen_ext32u_tl(cx_next, cx_next); 1377 cx_mask = ~0; 1378 } 1379 #endif 1380 1381 /* 1382 * The last iteration is handled outside the loop, so that cx_next 1383 * can never underflow. 1384 */ 1385 if (can_loop) { 1386 tcg_gen_brcondi_tl(TCG_COND_TSTEQ, cx_next, cx_mask, last); 1387 } 1388 1389 gen_set_label(loop); 1390 fn(s, ot, dshift); 1391 tcg_gen_mov_tl(cpu_regs[R_ECX], cx_next); 1392 gen_update_cc_op(s); 1393 1394 /* Leave if REP condition fails. */ 1395 if (is_repz_nz) { 1396 int nz = (s->prefix & PREFIX_REPNZ) ? 1 : 0; 1397 gen_jcc_noeob(s, (JCC_Z << 1) | (nz ^ 1), done); 1398 /* gen_prepare_eflags_z never changes cc_op. */ 1399 assert(!s->cc_op_dirty); 1400 } 1401 1402 if (can_loop) { 1403 tcg_gen_subi_tl(cx_next, cx_next, 1); 1404 tcg_gen_brcondi_tl(TCG_COND_TSTNE, cx_next, REP_MAX, loop); 1405 tcg_gen_brcondi_tl(TCG_COND_TSTEQ, cx_next, cx_mask, last); 1406 } 1407 1408 /* 1409 * Traps or interrupts set RF_MASK if they happen after any iteration 1410 * but the last. Set it here before giving the main loop a chance to 1411 * execute. (For faults, seg_helper.c sets the flag as usual). 1412 */ 1413 if (!had_rf) { 1414 gen_set_eflags(s, RF_MASK); 1415 } 1416 1417 /* Go to the main loop but reenter the same instruction. */ 1418 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1419 1420 if (can_loop) { 1421 /* 1422 * The last iteration needs no conditional jump, even if is_repz_nz, 1423 * because the repeats are ending anyway. 1424 */ 1425 gen_set_label(last); 1426 set_cc_op(s, CC_OP_DYNAMIC); 1427 fn(s, ot, dshift); 1428 tcg_gen_mov_tl(cpu_regs[R_ECX], cx_next); 1429 gen_update_cc_op(s); 1430 } 1431 1432 /* CX/ECX/RCX is zero, or REPZ/REPNZ broke the repetition. */ 1433 gen_set_label(done); 1434 set_cc_op(s, CC_OP_DYNAMIC); 1435 if (had_rf) { 1436 gen_reset_eflags(s, RF_MASK); 1437 } 1438 gen_jmp_rel_csize(s, 0, 1); 1439 } 1440 1441 static void do_gen_string(DisasContext *s, MemOp ot, 1442 void (*fn)(DisasContext *s, MemOp ot, TCGv dshift), 1443 bool is_repz_nz) 1444 { 1445 TCGv dshift = tcg_temp_new(); 1446 tcg_gen_ld32s_tl(dshift, tcg_env, offsetof(CPUX86State, df)); 1447 tcg_gen_shli_tl(dshift, dshift, ot); 1448 1449 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) { 1450 do_gen_rep(s, ot, dshift, fn, is_repz_nz); 1451 } else { 1452 fn(s, ot, dshift); 1453 } 1454 } 1455 1456 static void gen_repz(DisasContext *s, MemOp ot, 1457 void (*fn)(DisasContext *s, MemOp ot, TCGv dshift)) 1458 { 1459 do_gen_string(s, ot, fn, false); 1460 } 1461 1462 static void gen_repz_nz(DisasContext *s, MemOp ot, 1463 void (*fn)(DisasContext *s, MemOp ot, TCGv dshift)) 1464 { 1465 do_gen_string(s, ot, fn, true); 1466 } 1467 1468 static void gen_helper_fp_arith_ST0_FT0(int op) 1469 { 1470 switch (op) { 1471 case 0: 1472 gen_helper_fadd_ST0_FT0(tcg_env); 1473 break; 1474 case 1: 1475 gen_helper_fmul_ST0_FT0(tcg_env); 1476 break; 1477 case 2: 1478 gen_helper_fcom_ST0_FT0(tcg_env); 1479 break; 1480 case 3: 1481 gen_helper_fcom_ST0_FT0(tcg_env); 1482 break; 1483 case 4: 1484 gen_helper_fsub_ST0_FT0(tcg_env); 1485 break; 1486 case 5: 1487 gen_helper_fsubr_ST0_FT0(tcg_env); 1488 break; 1489 case 6: 1490 gen_helper_fdiv_ST0_FT0(tcg_env); 1491 break; 1492 case 7: 1493 gen_helper_fdivr_ST0_FT0(tcg_env); 1494 break; 1495 } 1496 } 1497 1498 /* NOTE the exception in "r" op ordering */ 1499 static void gen_helper_fp_arith_STN_ST0(int op, int opreg) 1500 { 1501 TCGv_i32 tmp = tcg_constant_i32(opreg); 1502 switch (op) { 1503 case 0: 1504 gen_helper_fadd_STN_ST0(tcg_env, tmp); 1505 break; 1506 case 1: 1507 gen_helper_fmul_STN_ST0(tcg_env, tmp); 1508 break; 1509 case 4: 1510 gen_helper_fsubr_STN_ST0(tcg_env, tmp); 1511 break; 1512 case 5: 1513 gen_helper_fsub_STN_ST0(tcg_env, tmp); 1514 break; 1515 case 6: 1516 gen_helper_fdivr_STN_ST0(tcg_env, tmp); 1517 break; 1518 case 7: 1519 gen_helper_fdiv_STN_ST0(tcg_env, tmp); 1520 break; 1521 } 1522 } 1523 1524 static void gen_exception(DisasContext *s, int trapno) 1525 { 1526 gen_update_cc_op(s); 1527 gen_update_eip_cur(s); 1528 gen_helper_raise_exception(tcg_env, tcg_constant_i32(trapno)); 1529 s->base.is_jmp = DISAS_NORETURN; 1530 } 1531 1532 /* Generate #UD for the current instruction. The assumption here is that 1533 the instruction is known, but it isn't allowed in the current cpu mode. */ 1534 static void gen_illegal_opcode(DisasContext *s) 1535 { 1536 gen_exception(s, EXCP06_ILLOP); 1537 } 1538 1539 /* Generate #GP for the current instruction. */ 1540 static void gen_exception_gpf(DisasContext *s) 1541 { 1542 gen_exception(s, EXCP0D_GPF); 1543 } 1544 1545 /* Check for cpl == 0; if not, raise #GP and return false. */ 1546 static bool check_cpl0(DisasContext *s) 1547 { 1548 if (CPL(s) == 0) { 1549 return true; 1550 } 1551 gen_exception_gpf(s); 1552 return false; 1553 } 1554 1555 /* XXX: add faster immediate case */ 1556 static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, 1557 bool is_right, TCGv count) 1558 { 1559 target_ulong mask = (ot == MO_64 ? 63 : 31); 1560 1561 switch (ot) { 1562 case MO_16: 1563 /* Note: we implement the Intel behaviour for shift count > 16. 1564 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A 1565 portion by constructing it as a 32-bit value. */ 1566 if (is_right) { 1567 tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16); 1568 tcg_gen_mov_tl(s->T1, s->T0); 1569 tcg_gen_mov_tl(s->T0, s->tmp0); 1570 } else { 1571 tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16); 1572 } 1573 /* 1574 * If TARGET_X86_64 defined then fall through into MO_32 case, 1575 * otherwise fall through default case. 1576 */ 1577 case MO_32: 1578 #ifdef TARGET_X86_64 1579 /* Concatenate the two 32-bit values and use a 64-bit shift. */ 1580 tcg_gen_subi_tl(s->tmp0, count, 1); 1581 if (is_right) { 1582 tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1); 1583 tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0); 1584 tcg_gen_shr_i64(s->T0, s->T0, count); 1585 } else { 1586 tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0); 1587 tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0); 1588 tcg_gen_shl_i64(s->T0, s->T0, count); 1589 tcg_gen_shri_i64(s->tmp0, s->tmp0, 32); 1590 tcg_gen_shri_i64(s->T0, s->T0, 32); 1591 } 1592 break; 1593 #endif 1594 default: 1595 tcg_gen_subi_tl(s->tmp0, count, 1); 1596 if (is_right) { 1597 tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0); 1598 1599 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1600 tcg_gen_shr_tl(s->T0, s->T0, count); 1601 tcg_gen_shl_tl(s->T1, s->T1, s->tmp4); 1602 } else { 1603 tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0); 1604 if (ot == MO_16) { 1605 /* Only needed if count > 16, for Intel behaviour. */ 1606 tcg_gen_subfi_tl(s->tmp4, 33, count); 1607 tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4); 1608 tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4); 1609 } 1610 1611 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1612 tcg_gen_shl_tl(s->T0, s->T0, count); 1613 tcg_gen_shr_tl(s->T1, s->T1, s->tmp4); 1614 } 1615 tcg_gen_movi_tl(s->tmp4, 0); 1616 tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4, 1617 s->tmp4, s->T1); 1618 tcg_gen_or_tl(s->T0, s->T0, s->T1); 1619 break; 1620 } 1621 } 1622 1623 #define X86_MAX_INSN_LENGTH 15 1624 1625 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes) 1626 { 1627 uint64_t pc = s->pc; 1628 1629 /* This is a subsequent insn that crosses a page boundary. */ 1630 if (s->base.num_insns > 1 && 1631 !translator_is_same_page(&s->base, s->pc + num_bytes - 1)) { 1632 siglongjmp(s->jmpbuf, 2); 1633 } 1634 1635 s->pc += num_bytes; 1636 if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) { 1637 /* If the instruction's 16th byte is on a different page than the 1st, a 1638 * page fault on the second page wins over the general protection fault 1639 * caused by the instruction being too long. 1640 * This can happen even if the operand is only one byte long! 1641 */ 1642 if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) { 1643 (void)translator_ldub(env, &s->base, 1644 (s->pc - 1) & TARGET_PAGE_MASK); 1645 } 1646 siglongjmp(s->jmpbuf, 1); 1647 } 1648 1649 return pc; 1650 } 1651 1652 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s) 1653 { 1654 return translator_ldub(env, &s->base, advance_pc(env, s, 1)); 1655 } 1656 1657 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s) 1658 { 1659 return translator_lduw(env, &s->base, advance_pc(env, s, 2)); 1660 } 1661 1662 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s) 1663 { 1664 return translator_ldl(env, &s->base, advance_pc(env, s, 4)); 1665 } 1666 1667 #ifdef TARGET_X86_64 1668 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s) 1669 { 1670 return translator_ldq(env, &s->base, advance_pc(env, s, 8)); 1671 } 1672 #endif 1673 1674 /* Decompose an address. */ 1675 1676 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s, 1677 int modrm, bool is_vsib) 1678 { 1679 int def_seg, base, index, scale, mod, rm; 1680 target_long disp; 1681 bool havesib; 1682 1683 def_seg = R_DS; 1684 index = -1; 1685 scale = 0; 1686 disp = 0; 1687 1688 mod = (modrm >> 6) & 3; 1689 rm = modrm & 7; 1690 base = rm | REX_B(s); 1691 1692 if (mod == 3) { 1693 /* Normally filtered out earlier, but including this path 1694 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */ 1695 goto done; 1696 } 1697 1698 switch (s->aflag) { 1699 case MO_64: 1700 case MO_32: 1701 havesib = 0; 1702 if (rm == 4) { 1703 int code = x86_ldub_code(env, s); 1704 scale = (code >> 6) & 3; 1705 index = ((code >> 3) & 7) | REX_X(s); 1706 if (index == 4 && !is_vsib) { 1707 index = -1; /* no index */ 1708 } 1709 base = (code & 7) | REX_B(s); 1710 havesib = 1; 1711 } 1712 1713 switch (mod) { 1714 case 0: 1715 if ((base & 7) == 5) { 1716 base = -1; 1717 disp = (int32_t)x86_ldl_code(env, s); 1718 if (CODE64(s) && !havesib) { 1719 base = -2; 1720 disp += s->pc + s->rip_offset; 1721 } 1722 } 1723 break; 1724 case 1: 1725 disp = (int8_t)x86_ldub_code(env, s); 1726 break; 1727 default: 1728 case 2: 1729 disp = (int32_t)x86_ldl_code(env, s); 1730 break; 1731 } 1732 1733 /* For correct popl handling with esp. */ 1734 if (base == R_ESP && s->popl_esp_hack) { 1735 disp += s->popl_esp_hack; 1736 } 1737 if (base == R_EBP || base == R_ESP) { 1738 def_seg = R_SS; 1739 } 1740 break; 1741 1742 case MO_16: 1743 if (mod == 0) { 1744 if (rm == 6) { 1745 base = -1; 1746 disp = x86_lduw_code(env, s); 1747 break; 1748 } 1749 } else if (mod == 1) { 1750 disp = (int8_t)x86_ldub_code(env, s); 1751 } else { 1752 disp = (int16_t)x86_lduw_code(env, s); 1753 } 1754 1755 switch (rm) { 1756 case 0: 1757 base = R_EBX; 1758 index = R_ESI; 1759 break; 1760 case 1: 1761 base = R_EBX; 1762 index = R_EDI; 1763 break; 1764 case 2: 1765 base = R_EBP; 1766 index = R_ESI; 1767 def_seg = R_SS; 1768 break; 1769 case 3: 1770 base = R_EBP; 1771 index = R_EDI; 1772 def_seg = R_SS; 1773 break; 1774 case 4: 1775 base = R_ESI; 1776 break; 1777 case 5: 1778 base = R_EDI; 1779 break; 1780 case 6: 1781 base = R_EBP; 1782 def_seg = R_SS; 1783 break; 1784 default: 1785 case 7: 1786 base = R_EBX; 1787 break; 1788 } 1789 break; 1790 1791 default: 1792 g_assert_not_reached(); 1793 } 1794 1795 done: 1796 return (AddressParts){ def_seg, base, index, scale, disp }; 1797 } 1798 1799 /* Compute the address, with a minimum number of TCG ops. */ 1800 static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib) 1801 { 1802 TCGv ea = NULL; 1803 1804 if (a.index >= 0 && !is_vsib) { 1805 if (a.scale == 0) { 1806 ea = cpu_regs[a.index]; 1807 } else { 1808 tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale); 1809 ea = s->A0; 1810 } 1811 if (a.base >= 0) { 1812 tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]); 1813 ea = s->A0; 1814 } 1815 } else if (a.base >= 0) { 1816 ea = cpu_regs[a.base]; 1817 } 1818 if (!ea) { 1819 if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) { 1820 /* With cpu_eip ~= pc_save, the expression is pc-relative. */ 1821 tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save); 1822 } else { 1823 tcg_gen_movi_tl(s->A0, a.disp); 1824 } 1825 ea = s->A0; 1826 } else if (a.disp != 0) { 1827 tcg_gen_addi_tl(s->A0, ea, a.disp); 1828 ea = s->A0; 1829 } 1830 1831 return ea; 1832 } 1833 1834 /* Used for BNDCL, BNDCU, BNDCN. */ 1835 static void gen_bndck(DisasContext *s, X86DecodedInsn *decode, 1836 TCGCond cond, TCGv_i64 bndv) 1837 { 1838 TCGv ea = gen_lea_modrm_1(s, decode->mem, false); 1839 1840 tcg_gen_extu_tl_i64(s->tmp1_i64, ea); 1841 if (!CODE64(s)) { 1842 tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64); 1843 } 1844 tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv); 1845 tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64); 1846 gen_helper_bndck(tcg_env, s->tmp2_i32); 1847 } 1848 1849 /* generate modrm load of memory or register. */ 1850 static void gen_ld_modrm(DisasContext *s, X86DecodedInsn *decode, MemOp ot) 1851 { 1852 int modrm = s->modrm; 1853 int mod, rm; 1854 1855 mod = (modrm >> 6) & 3; 1856 rm = (modrm & 7) | REX_B(s); 1857 if (mod == 3) { 1858 gen_op_mov_v_reg(s, ot, s->T0, rm); 1859 } else { 1860 gen_lea_modrm(s, decode); 1861 gen_op_ld_v(s, ot, s->T0, s->A0); 1862 } 1863 } 1864 1865 /* generate modrm store of memory or register. */ 1866 static void gen_st_modrm(DisasContext *s, X86DecodedInsn *decode, MemOp ot) 1867 { 1868 int modrm = s->modrm; 1869 int mod, rm; 1870 1871 mod = (modrm >> 6) & 3; 1872 rm = (modrm & 7) | REX_B(s); 1873 if (mod == 3) { 1874 gen_op_mov_reg_v(s, ot, rm, s->T0); 1875 } else { 1876 gen_lea_modrm(s, decode); 1877 gen_op_st_v(s, ot, s->T0, s->A0); 1878 } 1879 } 1880 1881 static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot) 1882 { 1883 target_ulong ret; 1884 1885 switch (ot) { 1886 case MO_8: 1887 ret = x86_ldub_code(env, s); 1888 break; 1889 case MO_16: 1890 ret = x86_lduw_code(env, s); 1891 break; 1892 case MO_32: 1893 ret = x86_ldl_code(env, s); 1894 break; 1895 #ifdef TARGET_X86_64 1896 case MO_64: 1897 ret = x86_ldq_code(env, s); 1898 break; 1899 #endif 1900 default: 1901 g_assert_not_reached(); 1902 } 1903 return ret; 1904 } 1905 1906 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot) 1907 { 1908 uint32_t ret; 1909 1910 switch (ot) { 1911 case MO_8: 1912 ret = x86_ldub_code(env, s); 1913 break; 1914 case MO_16: 1915 ret = x86_lduw_code(env, s); 1916 break; 1917 case MO_32: 1918 #ifdef TARGET_X86_64 1919 case MO_64: 1920 #endif 1921 ret = x86_ldl_code(env, s); 1922 break; 1923 default: 1924 g_assert_not_reached(); 1925 } 1926 return ret; 1927 } 1928 1929 static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot) 1930 { 1931 target_long ret; 1932 1933 switch (ot) { 1934 case MO_8: 1935 ret = (int8_t) x86_ldub_code(env, s); 1936 break; 1937 case MO_16: 1938 ret = (int16_t) x86_lduw_code(env, s); 1939 break; 1940 case MO_32: 1941 ret = (int32_t) x86_ldl_code(env, s); 1942 break; 1943 #ifdef TARGET_X86_64 1944 case MO_64: 1945 ret = x86_ldq_code(env, s); 1946 break; 1947 #endif 1948 default: 1949 g_assert_not_reached(); 1950 } 1951 return ret; 1952 } 1953 1954 static void gen_conditional_jump_labels(DisasContext *s, target_long diff, 1955 TCGLabel *not_taken, TCGLabel *taken) 1956 { 1957 if (not_taken) { 1958 gen_set_label(not_taken); 1959 } 1960 gen_jmp_rel_csize(s, 0, 1); 1961 1962 gen_set_label(taken); 1963 gen_jmp_rel(s, s->dflag, diff, 0); 1964 } 1965 1966 static void gen_cmovcc(DisasContext *s, int b, TCGv dest, TCGv src) 1967 { 1968 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1969 1970 if (!cc.use_reg2) { 1971 cc.reg2 = tcg_constant_tl(cc.imm); 1972 } 1973 1974 tcg_gen_movcond_tl(cc.cond, dest, cc.reg, cc.reg2, src, dest); 1975 } 1976 1977 static void gen_op_movl_seg_real(DisasContext *s, X86Seg seg_reg, TCGv seg) 1978 { 1979 TCGv selector = tcg_temp_new(); 1980 tcg_gen_ext16u_tl(selector, seg); 1981 tcg_gen_st32_tl(selector, tcg_env, 1982 offsetof(CPUX86State,segs[seg_reg].selector)); 1983 tcg_gen_shli_tl(cpu_seg_base[seg_reg], selector, 4); 1984 } 1985 1986 /* move SRC to seg_reg and compute if the CPU state may change. Never 1987 call this function with seg_reg == R_CS */ 1988 static void gen_movl_seg(DisasContext *s, X86Seg seg_reg, TCGv src) 1989 { 1990 if (PE(s) && !VM86(s)) { 1991 tcg_gen_trunc_tl_i32(s->tmp2_i32, src); 1992 gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32); 1993 /* abort translation because the addseg value may change or 1994 because ss32 may change. For R_SS, translation must always 1995 stop as a special handling must be done to disable hardware 1996 interrupts for the next instruction */ 1997 if (seg_reg == R_SS) { 1998 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 1999 } else if (CODE32(s) && seg_reg < R_FS) { 2000 s->base.is_jmp = DISAS_EOB_NEXT; 2001 } 2002 } else { 2003 gen_op_movl_seg_real(s, seg_reg, src); 2004 if (seg_reg == R_SS) { 2005 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 2006 } 2007 } 2008 } 2009 2010 static void gen_far_call(DisasContext *s) 2011 { 2012 TCGv_i32 new_cs = tcg_temp_new_i32(); 2013 tcg_gen_trunc_tl_i32(new_cs, s->T1); 2014 if (PE(s) && !VM86(s)) { 2015 gen_helper_lcall_protected(tcg_env, new_cs, s->T0, 2016 tcg_constant_i32(s->dflag - 1), 2017 eip_next_tl(s)); 2018 } else { 2019 TCGv_i32 new_eip = tcg_temp_new_i32(); 2020 tcg_gen_trunc_tl_i32(new_eip, s->T0); 2021 gen_helper_lcall_real(tcg_env, new_cs, new_eip, 2022 tcg_constant_i32(s->dflag - 1), 2023 eip_next_i32(s)); 2024 } 2025 s->base.is_jmp = DISAS_JUMP; 2026 } 2027 2028 static void gen_far_jmp(DisasContext *s) 2029 { 2030 if (PE(s) && !VM86(s)) { 2031 TCGv_i32 new_cs = tcg_temp_new_i32(); 2032 tcg_gen_trunc_tl_i32(new_cs, s->T1); 2033 gen_helper_ljmp_protected(tcg_env, new_cs, s->T0, 2034 eip_next_tl(s)); 2035 } else { 2036 gen_op_movl_seg_real(s, R_CS, s->T1); 2037 gen_op_jmp_v(s, s->T0); 2038 } 2039 s->base.is_jmp = DISAS_JUMP; 2040 } 2041 2042 static void gen_svm_check_intercept(DisasContext *s, uint32_t type) 2043 { 2044 /* no SVM activated; fast case */ 2045 if (likely(!GUEST(s))) { 2046 return; 2047 } 2048 gen_helper_svm_check_intercept(tcg_env, tcg_constant_i32(type)); 2049 } 2050 2051 static inline void gen_stack_update(DisasContext *s, int addend) 2052 { 2053 gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend); 2054 } 2055 2056 static void gen_lea_ss_ofs(DisasContext *s, TCGv dest, TCGv src, target_ulong offset) 2057 { 2058 if (offset) { 2059 tcg_gen_addi_tl(dest, src, offset); 2060 src = dest; 2061 } 2062 gen_lea_v_seg_dest(s, mo_stacksize(s), dest, src, R_SS, -1); 2063 } 2064 2065 /* Generate a push. It depends on ss32, addseg and dflag. */ 2066 static void gen_push_v(DisasContext *s, TCGv val) 2067 { 2068 MemOp d_ot = mo_pushpop(s, s->dflag); 2069 MemOp a_ot = mo_stacksize(s); 2070 int size = 1 << d_ot; 2071 TCGv new_esp = tcg_temp_new(); 2072 2073 tcg_gen_subi_tl(new_esp, cpu_regs[R_ESP], size); 2074 2075 /* Now reduce the value to the address size and apply SS base. */ 2076 gen_lea_ss_ofs(s, s->A0, new_esp, 0); 2077 gen_op_st_v(s, d_ot, val, s->A0); 2078 gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp); 2079 } 2080 2081 /* two step pop is necessary for precise exceptions */ 2082 static MemOp gen_pop_T0(DisasContext *s) 2083 { 2084 MemOp d_ot = mo_pushpop(s, s->dflag); 2085 2086 gen_lea_ss_ofs(s, s->T0, cpu_regs[R_ESP], 0); 2087 gen_op_ld_v(s, d_ot, s->T0, s->T0); 2088 2089 return d_ot; 2090 } 2091 2092 static inline void gen_pop_update(DisasContext *s, MemOp ot) 2093 { 2094 gen_stack_update(s, 1 << ot); 2095 } 2096 2097 static void gen_pusha(DisasContext *s) 2098 { 2099 MemOp d_ot = s->dflag; 2100 int size = 1 << d_ot; 2101 int i; 2102 2103 for (i = 0; i < 8; i++) { 2104 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], (i - 8) * size); 2105 gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0); 2106 } 2107 2108 gen_stack_update(s, -8 * size); 2109 } 2110 2111 static void gen_popa(DisasContext *s) 2112 { 2113 MemOp d_ot = s->dflag; 2114 int size = 1 << d_ot; 2115 int i; 2116 2117 for (i = 0; i < 8; i++) { 2118 /* ESP is not reloaded */ 2119 if (7 - i == R_ESP) { 2120 continue; 2121 } 2122 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], i * size); 2123 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2124 gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0); 2125 } 2126 2127 gen_stack_update(s, 8 * size); 2128 } 2129 2130 static void gen_enter(DisasContext *s, int esp_addend, int level) 2131 { 2132 MemOp d_ot = mo_pushpop(s, s->dflag); 2133 MemOp a_ot = mo_stacksize(s); 2134 int size = 1 << d_ot; 2135 2136 /* Push BP; compute FrameTemp into T1. */ 2137 tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size); 2138 gen_lea_ss_ofs(s, s->A0, s->T1, 0); 2139 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0); 2140 2141 level &= 31; 2142 if (level != 0) { 2143 int i; 2144 2145 /* Copy level-1 pointers from the previous frame. */ 2146 for (i = 1; i < level; ++i) { 2147 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], -size * i); 2148 gen_op_ld_v(s, d_ot, s->tmp0, s->A0); 2149 2150 gen_lea_ss_ofs(s, s->A0, s->T1, -size * i); 2151 gen_op_st_v(s, d_ot, s->tmp0, s->A0); 2152 } 2153 2154 /* Push the current FrameTemp as the last level. */ 2155 gen_lea_ss_ofs(s, s->A0, s->T1, -size * level); 2156 gen_op_st_v(s, d_ot, s->T1, s->A0); 2157 } 2158 2159 /* Copy the FrameTemp value to EBP. */ 2160 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T1); 2161 2162 /* Compute the final value of ESP. */ 2163 tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level); 2164 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2165 } 2166 2167 static void gen_leave(DisasContext *s) 2168 { 2169 MemOp d_ot = mo_pushpop(s, s->dflag); 2170 MemOp a_ot = mo_stacksize(s); 2171 2172 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], 0); 2173 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2174 2175 tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot); 2176 2177 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0); 2178 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2179 } 2180 2181 /* Similarly, except that the assumption here is that we don't decode 2182 the instruction at all -- either a missing opcode, an unimplemented 2183 feature, or just a bogus instruction stream. */ 2184 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) 2185 { 2186 gen_illegal_opcode(s); 2187 2188 if (qemu_loglevel_mask(LOG_UNIMP)) { 2189 FILE *logfile = qemu_log_trylock(); 2190 if (logfile) { 2191 target_ulong pc = s->base.pc_next, end = s->pc; 2192 2193 fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc); 2194 for (; pc < end; ++pc) { 2195 fprintf(logfile, " %02x", translator_ldub(env, &s->base, pc)); 2196 } 2197 fprintf(logfile, "\n"); 2198 qemu_log_unlock(logfile); 2199 } 2200 } 2201 } 2202 2203 /* an interrupt is different from an exception because of the 2204 privilege checks */ 2205 static void gen_interrupt(DisasContext *s, uint8_t intno) 2206 { 2207 gen_update_cc_op(s); 2208 gen_update_eip_cur(s); 2209 gen_helper_raise_interrupt(tcg_env, tcg_constant_i32(intno), 2210 cur_insn_len_i32(s)); 2211 s->base.is_jmp = DISAS_NORETURN; 2212 } 2213 2214 /* Clear BND registers during legacy branches. */ 2215 static void gen_bnd_jmp(DisasContext *s) 2216 { 2217 /* Clear the registers only if BND prefix is missing, MPX is enabled, 2218 and if the BNDREGs are known to be in use (non-zero) already. 2219 The helper itself will check BNDPRESERVE at runtime. */ 2220 if ((s->prefix & PREFIX_REPNZ) == 0 2221 && (s->flags & HF_MPX_EN_MASK) != 0 2222 && (s->flags & HF_MPX_IU_MASK) != 0) { 2223 gen_helper_bnd_jmp(tcg_env); 2224 } 2225 } 2226 2227 /* 2228 * Generate an end of block, including common tasks such as generating 2229 * single step traps, resetting the RF flag, and handling the interrupt 2230 * shadow. 2231 */ 2232 static void 2233 gen_eob(DisasContext *s, int mode) 2234 { 2235 bool inhibit_reset; 2236 2237 gen_update_cc_op(s); 2238 2239 /* If several instructions disable interrupts, only the first does it. */ 2240 inhibit_reset = false; 2241 if (s->flags & HF_INHIBIT_IRQ_MASK) { 2242 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); 2243 inhibit_reset = true; 2244 } else if (mode == DISAS_EOB_INHIBIT_IRQ) { 2245 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); 2246 } 2247 2248 if (s->flags & HF_RF_MASK) { 2249 gen_reset_eflags(s, RF_MASK); 2250 } 2251 if (mode == DISAS_EOB_RECHECK_TF) { 2252 gen_helper_rechecking_single_step(tcg_env); 2253 tcg_gen_exit_tb(NULL, 0); 2254 } else if ((s->flags & HF_TF_MASK) && mode != DISAS_EOB_INHIBIT_IRQ) { 2255 gen_helper_single_step(tcg_env); 2256 } else if (mode == DISAS_JUMP && 2257 /* give irqs a chance to happen */ 2258 !inhibit_reset) { 2259 tcg_gen_lookup_and_goto_ptr(); 2260 } else { 2261 tcg_gen_exit_tb(NULL, 0); 2262 } 2263 2264 s->base.is_jmp = DISAS_NORETURN; 2265 } 2266 2267 /* Jump to eip+diff, truncating the result to OT. */ 2268 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num) 2269 { 2270 bool use_goto_tb = s->jmp_opt; 2271 target_ulong mask = -1; 2272 target_ulong new_pc = s->pc + diff; 2273 target_ulong new_eip = new_pc - s->cs_base; 2274 2275 assert(!s->cc_op_dirty); 2276 2277 /* In 64-bit mode, operand size is fixed at 64 bits. */ 2278 if (!CODE64(s)) { 2279 if (ot == MO_16) { 2280 mask = 0xffff; 2281 if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) { 2282 use_goto_tb = false; 2283 } 2284 } else { 2285 mask = 0xffffffff; 2286 } 2287 } 2288 new_eip &= mask; 2289 2290 if (tb_cflags(s->base.tb) & CF_PCREL) { 2291 tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save); 2292 /* 2293 * If we can prove the branch does not leave the page and we have 2294 * no extra masking to apply (data16 branch in code32, see above), 2295 * then we have also proven that the addition does not wrap. 2296 */ 2297 if (!use_goto_tb || !translator_is_same_page(&s->base, new_pc)) { 2298 tcg_gen_andi_tl(cpu_eip, cpu_eip, mask); 2299 use_goto_tb = false; 2300 } 2301 } else if (!CODE64(s)) { 2302 new_pc = (uint32_t)(new_eip + s->cs_base); 2303 } 2304 2305 if (use_goto_tb && translator_use_goto_tb(&s->base, new_pc)) { 2306 /* jump to same page: we can use a direct jump */ 2307 tcg_gen_goto_tb(tb_num); 2308 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2309 tcg_gen_movi_tl(cpu_eip, new_eip); 2310 } 2311 tcg_gen_exit_tb(s->base.tb, tb_num); 2312 s->base.is_jmp = DISAS_NORETURN; 2313 } else { 2314 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2315 tcg_gen_movi_tl(cpu_eip, new_eip); 2316 } 2317 if (s->jmp_opt) { 2318 gen_eob(s, DISAS_JUMP); /* jump to another page */ 2319 } else { 2320 gen_eob(s, DISAS_EOB_ONLY); /* exit to main loop */ 2321 } 2322 } 2323 } 2324 2325 /* Jump to eip+diff, truncating to the current code size. */ 2326 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num) 2327 { 2328 /* CODE64 ignores the OT argument, so we need not consider it. */ 2329 gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num); 2330 } 2331 2332 static inline void gen_ldq_env_A0(DisasContext *s, int offset) 2333 { 2334 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2335 tcg_gen_st_i64(s->tmp1_i64, tcg_env, offset); 2336 } 2337 2338 static inline void gen_stq_env_A0(DisasContext *s, int offset) 2339 { 2340 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, offset); 2341 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2342 } 2343 2344 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align) 2345 { 2346 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2347 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2348 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2349 int mem_index = s->mem_index; 2350 TCGv_i128 t = tcg_temp_new_i128(); 2351 2352 tcg_gen_qemu_ld_i128(t, s->A0, mem_index, mop); 2353 tcg_gen_st_i128(t, tcg_env, offset); 2354 } 2355 2356 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align) 2357 { 2358 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2359 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2360 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2361 int mem_index = s->mem_index; 2362 TCGv_i128 t = tcg_temp_new_i128(); 2363 2364 tcg_gen_ld_i128(t, tcg_env, offset); 2365 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop); 2366 } 2367 2368 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align) 2369 { 2370 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2371 int mem_index = s->mem_index; 2372 TCGv_i128 t0 = tcg_temp_new_i128(); 2373 TCGv_i128 t1 = tcg_temp_new_i128(); 2374 2375 tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2376 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2377 tcg_gen_qemu_ld_i128(t1, s->tmp0, mem_index, mop); 2378 2379 tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2380 tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2381 } 2382 2383 static void gen_sty_env_A0(DisasContext *s, int offset, bool align) 2384 { 2385 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2386 int mem_index = s->mem_index; 2387 TCGv_i128 t = tcg_temp_new_i128(); 2388 2389 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2390 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2391 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2392 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2393 tcg_gen_qemu_st_i128(t, s->tmp0, mem_index, mop); 2394 } 2395 2396 #include "emit.c.inc" 2397 2398 static void gen_x87(DisasContext *s, X86DecodedInsn *decode) 2399 { 2400 bool update_fip = true; 2401 int b = decode->b; 2402 int modrm = s->modrm; 2403 int mod, rm, op; 2404 2405 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 2406 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 2407 /* XXX: what to do if illegal op ? */ 2408 gen_exception(s, EXCP07_PREX); 2409 return; 2410 } 2411 mod = (modrm >> 6) & 3; 2412 rm = modrm & 7; 2413 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 2414 if (mod != 3) { 2415 /* memory op */ 2416 TCGv ea = gen_lea_modrm_1(s, decode->mem, false); 2417 TCGv last_addr = tcg_temp_new(); 2418 bool update_fdp = true; 2419 2420 tcg_gen_mov_tl(last_addr, ea); 2421 gen_lea_v_seg(s, ea, decode->mem.def_seg, s->override); 2422 2423 switch (op) { 2424 case 0x00 ... 0x07: /* fxxxs */ 2425 case 0x10 ... 0x17: /* fixxxl */ 2426 case 0x20 ... 0x27: /* fxxxl */ 2427 case 0x30 ... 0x37: /* fixxx */ 2428 { 2429 int op1; 2430 op1 = op & 7; 2431 2432 switch (op >> 4) { 2433 case 0: 2434 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2435 s->mem_index, MO_LEUL); 2436 gen_helper_flds_FT0(tcg_env, s->tmp2_i32); 2437 break; 2438 case 1: 2439 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2440 s->mem_index, MO_LEUL); 2441 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2442 break; 2443 case 2: 2444 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2445 s->mem_index, MO_LEUQ); 2446 gen_helper_fldl_FT0(tcg_env, s->tmp1_i64); 2447 break; 2448 case 3: 2449 default: 2450 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2451 s->mem_index, MO_LESW); 2452 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2453 break; 2454 } 2455 2456 gen_helper_fp_arith_ST0_FT0(op1); 2457 if (op1 == 3) { 2458 /* fcomp needs pop */ 2459 gen_helper_fpop(tcg_env); 2460 } 2461 } 2462 break; 2463 case 0x08: /* flds */ 2464 case 0x0a: /* fsts */ 2465 case 0x0b: /* fstps */ 2466 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 2467 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 2468 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 2469 switch (op & 7) { 2470 case 0: 2471 switch (op >> 4) { 2472 case 0: 2473 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2474 s->mem_index, MO_LEUL); 2475 gen_helper_flds_ST0(tcg_env, s->tmp2_i32); 2476 break; 2477 case 1: 2478 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2479 s->mem_index, MO_LEUL); 2480 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2481 break; 2482 case 2: 2483 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2484 s->mem_index, MO_LEUQ); 2485 gen_helper_fldl_ST0(tcg_env, s->tmp1_i64); 2486 break; 2487 case 3: 2488 default: 2489 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2490 s->mem_index, MO_LESW); 2491 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2492 break; 2493 } 2494 break; 2495 case 1: 2496 /* XXX: the corresponding CPUID bit must be tested ! */ 2497 switch (op >> 4) { 2498 case 1: 2499 gen_helper_fisttl_ST0(s->tmp2_i32, tcg_env); 2500 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2501 s->mem_index, MO_LEUL); 2502 break; 2503 case 2: 2504 gen_helper_fisttll_ST0(s->tmp1_i64, tcg_env); 2505 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2506 s->mem_index, MO_LEUQ); 2507 break; 2508 case 3: 2509 default: 2510 gen_helper_fistt_ST0(s->tmp2_i32, tcg_env); 2511 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2512 s->mem_index, MO_LEUW); 2513 break; 2514 } 2515 gen_helper_fpop(tcg_env); 2516 break; 2517 default: 2518 switch (op >> 4) { 2519 case 0: 2520 gen_helper_fsts_ST0(s->tmp2_i32, tcg_env); 2521 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2522 s->mem_index, MO_LEUL); 2523 break; 2524 case 1: 2525 gen_helper_fistl_ST0(s->tmp2_i32, tcg_env); 2526 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2527 s->mem_index, MO_LEUL); 2528 break; 2529 case 2: 2530 gen_helper_fstl_ST0(s->tmp1_i64, tcg_env); 2531 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2532 s->mem_index, MO_LEUQ); 2533 break; 2534 case 3: 2535 default: 2536 gen_helper_fist_ST0(s->tmp2_i32, tcg_env); 2537 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2538 s->mem_index, MO_LEUW); 2539 break; 2540 } 2541 if ((op & 7) == 3) { 2542 gen_helper_fpop(tcg_env); 2543 } 2544 break; 2545 } 2546 break; 2547 case 0x0c: /* fldenv mem */ 2548 gen_helper_fldenv(tcg_env, s->A0, 2549 tcg_constant_i32(s->dflag - 1)); 2550 update_fip = update_fdp = false; 2551 break; 2552 case 0x0d: /* fldcw mem */ 2553 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2554 s->mem_index, MO_LEUW); 2555 gen_helper_fldcw(tcg_env, s->tmp2_i32); 2556 update_fip = update_fdp = false; 2557 break; 2558 case 0x0e: /* fnstenv mem */ 2559 gen_helper_fstenv(tcg_env, s->A0, 2560 tcg_constant_i32(s->dflag - 1)); 2561 update_fip = update_fdp = false; 2562 break; 2563 case 0x0f: /* fnstcw mem */ 2564 gen_helper_fnstcw(s->tmp2_i32, tcg_env); 2565 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2566 s->mem_index, MO_LEUW); 2567 update_fip = update_fdp = false; 2568 break; 2569 case 0x1d: /* fldt mem */ 2570 gen_helper_fldt_ST0(tcg_env, s->A0); 2571 break; 2572 case 0x1f: /* fstpt mem */ 2573 gen_helper_fstt_ST0(tcg_env, s->A0); 2574 gen_helper_fpop(tcg_env); 2575 break; 2576 case 0x2c: /* frstor mem */ 2577 gen_helper_frstor(tcg_env, s->A0, 2578 tcg_constant_i32(s->dflag - 1)); 2579 update_fip = update_fdp = false; 2580 break; 2581 case 0x2e: /* fnsave mem */ 2582 gen_helper_fsave(tcg_env, s->A0, 2583 tcg_constant_i32(s->dflag - 1)); 2584 update_fip = update_fdp = false; 2585 break; 2586 case 0x2f: /* fnstsw mem */ 2587 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2588 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2589 s->mem_index, MO_LEUW); 2590 update_fip = update_fdp = false; 2591 break; 2592 case 0x3c: /* fbld */ 2593 gen_helper_fbld_ST0(tcg_env, s->A0); 2594 break; 2595 case 0x3e: /* fbstp */ 2596 gen_helper_fbst_ST0(tcg_env, s->A0); 2597 gen_helper_fpop(tcg_env); 2598 break; 2599 case 0x3d: /* fildll */ 2600 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2601 s->mem_index, MO_LEUQ); 2602 gen_helper_fildll_ST0(tcg_env, s->tmp1_i64); 2603 break; 2604 case 0x3f: /* fistpll */ 2605 gen_helper_fistll_ST0(s->tmp1_i64, tcg_env); 2606 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2607 s->mem_index, MO_LEUQ); 2608 gen_helper_fpop(tcg_env); 2609 break; 2610 default: 2611 goto illegal_op; 2612 } 2613 2614 if (update_fdp) { 2615 int last_seg = s->override >= 0 ? s->override : decode->mem.def_seg; 2616 2617 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 2618 offsetof(CPUX86State, 2619 segs[last_seg].selector)); 2620 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 2621 offsetof(CPUX86State, fpds)); 2622 tcg_gen_st_tl(last_addr, tcg_env, 2623 offsetof(CPUX86State, fpdp)); 2624 } 2625 } else { 2626 /* register float ops */ 2627 int opreg = rm; 2628 2629 switch (op) { 2630 case 0x08: /* fld sti */ 2631 gen_helper_fpush(tcg_env); 2632 gen_helper_fmov_ST0_STN(tcg_env, 2633 tcg_constant_i32((opreg + 1) & 7)); 2634 break; 2635 case 0x09: /* fxchg sti */ 2636 case 0x29: /* fxchg4 sti, undocumented op */ 2637 case 0x39: /* fxchg7 sti, undocumented op */ 2638 gen_helper_fxchg_ST0_STN(tcg_env, tcg_constant_i32(opreg)); 2639 break; 2640 case 0x0a: /* grp d9/2 */ 2641 switch (rm) { 2642 case 0: /* fnop */ 2643 /* 2644 * check exceptions (FreeBSD FPU probe) 2645 * needs to be treated as I/O because of ferr_irq 2646 */ 2647 translator_io_start(&s->base); 2648 gen_helper_fwait(tcg_env); 2649 update_fip = false; 2650 break; 2651 default: 2652 goto illegal_op; 2653 } 2654 break; 2655 case 0x0c: /* grp d9/4 */ 2656 switch (rm) { 2657 case 0: /* fchs */ 2658 gen_helper_fchs_ST0(tcg_env); 2659 break; 2660 case 1: /* fabs */ 2661 gen_helper_fabs_ST0(tcg_env); 2662 break; 2663 case 4: /* ftst */ 2664 gen_helper_fldz_FT0(tcg_env); 2665 gen_helper_fcom_ST0_FT0(tcg_env); 2666 break; 2667 case 5: /* fxam */ 2668 gen_helper_fxam_ST0(tcg_env); 2669 break; 2670 default: 2671 goto illegal_op; 2672 } 2673 break; 2674 case 0x0d: /* grp d9/5 */ 2675 { 2676 switch (rm) { 2677 case 0: 2678 gen_helper_fpush(tcg_env); 2679 gen_helper_fld1_ST0(tcg_env); 2680 break; 2681 case 1: 2682 gen_helper_fpush(tcg_env); 2683 gen_helper_fldl2t_ST0(tcg_env); 2684 break; 2685 case 2: 2686 gen_helper_fpush(tcg_env); 2687 gen_helper_fldl2e_ST0(tcg_env); 2688 break; 2689 case 3: 2690 gen_helper_fpush(tcg_env); 2691 gen_helper_fldpi_ST0(tcg_env); 2692 break; 2693 case 4: 2694 gen_helper_fpush(tcg_env); 2695 gen_helper_fldlg2_ST0(tcg_env); 2696 break; 2697 case 5: 2698 gen_helper_fpush(tcg_env); 2699 gen_helper_fldln2_ST0(tcg_env); 2700 break; 2701 case 6: 2702 gen_helper_fpush(tcg_env); 2703 gen_helper_fldz_ST0(tcg_env); 2704 break; 2705 default: 2706 goto illegal_op; 2707 } 2708 } 2709 break; 2710 case 0x0e: /* grp d9/6 */ 2711 switch (rm) { 2712 case 0: /* f2xm1 */ 2713 gen_helper_f2xm1(tcg_env); 2714 break; 2715 case 1: /* fyl2x */ 2716 gen_helper_fyl2x(tcg_env); 2717 break; 2718 case 2: /* fptan */ 2719 gen_helper_fptan(tcg_env); 2720 break; 2721 case 3: /* fpatan */ 2722 gen_helper_fpatan(tcg_env); 2723 break; 2724 case 4: /* fxtract */ 2725 gen_helper_fxtract(tcg_env); 2726 break; 2727 case 5: /* fprem1 */ 2728 gen_helper_fprem1(tcg_env); 2729 break; 2730 case 6: /* fdecstp */ 2731 gen_helper_fdecstp(tcg_env); 2732 break; 2733 default: 2734 case 7: /* fincstp */ 2735 gen_helper_fincstp(tcg_env); 2736 break; 2737 } 2738 break; 2739 case 0x0f: /* grp d9/7 */ 2740 switch (rm) { 2741 case 0: /* fprem */ 2742 gen_helper_fprem(tcg_env); 2743 break; 2744 case 1: /* fyl2xp1 */ 2745 gen_helper_fyl2xp1(tcg_env); 2746 break; 2747 case 2: /* fsqrt */ 2748 gen_helper_fsqrt(tcg_env); 2749 break; 2750 case 3: /* fsincos */ 2751 gen_helper_fsincos(tcg_env); 2752 break; 2753 case 5: /* fscale */ 2754 gen_helper_fscale(tcg_env); 2755 break; 2756 case 4: /* frndint */ 2757 gen_helper_frndint(tcg_env); 2758 break; 2759 case 6: /* fsin */ 2760 gen_helper_fsin(tcg_env); 2761 break; 2762 default: 2763 case 7: /* fcos */ 2764 gen_helper_fcos(tcg_env); 2765 break; 2766 } 2767 break; 2768 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 2769 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 2770 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 2771 { 2772 int op1; 2773 2774 op1 = op & 7; 2775 if (op >= 0x20) { 2776 gen_helper_fp_arith_STN_ST0(op1, opreg); 2777 if (op >= 0x30) { 2778 gen_helper_fpop(tcg_env); 2779 } 2780 } else { 2781 gen_helper_fmov_FT0_STN(tcg_env, 2782 tcg_constant_i32(opreg)); 2783 gen_helper_fp_arith_ST0_FT0(op1); 2784 } 2785 } 2786 break; 2787 case 0x02: /* fcom */ 2788 case 0x22: /* fcom2, undocumented op */ 2789 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2790 gen_helper_fcom_ST0_FT0(tcg_env); 2791 break; 2792 case 0x03: /* fcomp */ 2793 case 0x23: /* fcomp3, undocumented op */ 2794 case 0x32: /* fcomp5, undocumented op */ 2795 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2796 gen_helper_fcom_ST0_FT0(tcg_env); 2797 gen_helper_fpop(tcg_env); 2798 break; 2799 case 0x15: /* da/5 */ 2800 switch (rm) { 2801 case 1: /* fucompp */ 2802 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2803 gen_helper_fucom_ST0_FT0(tcg_env); 2804 gen_helper_fpop(tcg_env); 2805 gen_helper_fpop(tcg_env); 2806 break; 2807 default: 2808 goto illegal_op; 2809 } 2810 break; 2811 case 0x1c: 2812 switch (rm) { 2813 case 0: /* feni (287 only, just do nop here) */ 2814 break; 2815 case 1: /* fdisi (287 only, just do nop here) */ 2816 break; 2817 case 2: /* fclex */ 2818 gen_helper_fclex(tcg_env); 2819 update_fip = false; 2820 break; 2821 case 3: /* fninit */ 2822 gen_helper_fninit(tcg_env); 2823 update_fip = false; 2824 break; 2825 case 4: /* fsetpm (287 only, just do nop here) */ 2826 break; 2827 default: 2828 goto illegal_op; 2829 } 2830 break; 2831 case 0x1d: /* fucomi */ 2832 if (!(s->cpuid_features & CPUID_CMOV)) { 2833 goto illegal_op; 2834 } 2835 gen_update_cc_op(s); 2836 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2837 gen_helper_fucomi_ST0_FT0(tcg_env); 2838 assume_cc_op(s, CC_OP_EFLAGS); 2839 break; 2840 case 0x1e: /* fcomi */ 2841 if (!(s->cpuid_features & CPUID_CMOV)) { 2842 goto illegal_op; 2843 } 2844 gen_update_cc_op(s); 2845 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2846 gen_helper_fcomi_ST0_FT0(tcg_env); 2847 assume_cc_op(s, CC_OP_EFLAGS); 2848 break; 2849 case 0x28: /* ffree sti */ 2850 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2851 break; 2852 case 0x2a: /* fst sti */ 2853 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2854 break; 2855 case 0x2b: /* fstp sti */ 2856 case 0x0b: /* fstp1 sti, undocumented op */ 2857 case 0x3a: /* fstp8 sti, undocumented op */ 2858 case 0x3b: /* fstp9 sti, undocumented op */ 2859 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2860 gen_helper_fpop(tcg_env); 2861 break; 2862 case 0x2c: /* fucom st(i) */ 2863 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2864 gen_helper_fucom_ST0_FT0(tcg_env); 2865 break; 2866 case 0x2d: /* fucomp st(i) */ 2867 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2868 gen_helper_fucom_ST0_FT0(tcg_env); 2869 gen_helper_fpop(tcg_env); 2870 break; 2871 case 0x33: /* de/3 */ 2872 switch (rm) { 2873 case 1: /* fcompp */ 2874 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2875 gen_helper_fcom_ST0_FT0(tcg_env); 2876 gen_helper_fpop(tcg_env); 2877 gen_helper_fpop(tcg_env); 2878 break; 2879 default: 2880 goto illegal_op; 2881 } 2882 break; 2883 case 0x38: /* ffreep sti, undocumented op */ 2884 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2885 gen_helper_fpop(tcg_env); 2886 break; 2887 case 0x3c: /* df/4 */ 2888 switch (rm) { 2889 case 0: 2890 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2891 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 2892 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 2893 break; 2894 default: 2895 goto illegal_op; 2896 } 2897 break; 2898 case 0x3d: /* fucomip */ 2899 if (!(s->cpuid_features & CPUID_CMOV)) { 2900 goto illegal_op; 2901 } 2902 gen_update_cc_op(s); 2903 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2904 gen_helper_fucomi_ST0_FT0(tcg_env); 2905 gen_helper_fpop(tcg_env); 2906 assume_cc_op(s, CC_OP_EFLAGS); 2907 break; 2908 case 0x3e: /* fcomip */ 2909 if (!(s->cpuid_features & CPUID_CMOV)) { 2910 goto illegal_op; 2911 } 2912 gen_update_cc_op(s); 2913 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2914 gen_helper_fcomi_ST0_FT0(tcg_env); 2915 gen_helper_fpop(tcg_env); 2916 assume_cc_op(s, CC_OP_EFLAGS); 2917 break; 2918 case 0x10 ... 0x13: /* fcmovxx */ 2919 case 0x18 ... 0x1b: 2920 { 2921 int op1; 2922 TCGLabel *l1; 2923 static const uint8_t fcmov_cc[8] = { 2924 (JCC_B << 1), 2925 (JCC_Z << 1), 2926 (JCC_BE << 1), 2927 (JCC_P << 1), 2928 }; 2929 2930 if (!(s->cpuid_features & CPUID_CMOV)) { 2931 goto illegal_op; 2932 } 2933 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 2934 l1 = gen_new_label(); 2935 gen_jcc_noeob(s, op1, l1); 2936 gen_helper_fmov_ST0_STN(tcg_env, 2937 tcg_constant_i32(opreg)); 2938 gen_set_label(l1); 2939 } 2940 break; 2941 default: 2942 goto illegal_op; 2943 } 2944 } 2945 2946 if (update_fip) { 2947 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 2948 offsetof(CPUX86State, segs[R_CS].selector)); 2949 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 2950 offsetof(CPUX86State, fpcs)); 2951 tcg_gen_st_tl(eip_cur_tl(s), 2952 tcg_env, offsetof(CPUX86State, fpip)); 2953 } 2954 return; 2955 2956 illegal_op: 2957 gen_illegal_opcode(s); 2958 } 2959 2960 static void gen_multi0F(DisasContext *s, X86DecodedInsn *decode) 2961 { 2962 int prefixes = s->prefix; 2963 MemOp dflag = s->dflag; 2964 int b = decode->b + 0x100; 2965 int modrm = s->modrm; 2966 MemOp ot; 2967 int reg, rm, mod, op; 2968 2969 /* now check op code */ 2970 switch (b) { 2971 case 0x1c7: /* RDSEED, RDPID with f3 prefix */ 2972 mod = (modrm >> 6) & 3; 2973 switch ((modrm >> 3) & 7) { 2974 case 7: 2975 if (mod != 3 || 2976 (s->prefix & PREFIX_REPNZ)) { 2977 goto illegal_op; 2978 } 2979 if (s->prefix & PREFIX_REPZ) { 2980 if (!(s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_RDPID)) { 2981 goto illegal_op; 2982 } 2983 gen_helper_rdpid(s->T0, tcg_env); 2984 rm = (modrm & 7) | REX_B(s); 2985 gen_op_mov_reg_v(s, dflag, rm, s->T0); 2986 break; 2987 } else { 2988 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) { 2989 goto illegal_op; 2990 } 2991 goto do_rdrand; 2992 } 2993 2994 case 6: /* RDRAND */ 2995 if (mod != 3 || 2996 (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) || 2997 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { 2998 goto illegal_op; 2999 } 3000 do_rdrand: 3001 translator_io_start(&s->base); 3002 gen_helper_rdrand(s->T0, tcg_env); 3003 rm = (modrm & 7) | REX_B(s); 3004 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3005 assume_cc_op(s, CC_OP_EFLAGS); 3006 break; 3007 3008 default: 3009 goto illegal_op; 3010 } 3011 break; 3012 3013 case 0x100: 3014 mod = (modrm >> 6) & 3; 3015 op = (modrm >> 3) & 7; 3016 switch(op) { 3017 case 0: /* sldt */ 3018 if (!PE(s) || VM86(s)) 3019 goto illegal_op; 3020 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3021 break; 3022 } 3023 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ); 3024 tcg_gen_ld32u_tl(s->T0, tcg_env, 3025 offsetof(CPUX86State, ldt.selector)); 3026 ot = mod == 3 ? dflag : MO_16; 3027 gen_st_modrm(s, decode, ot); 3028 break; 3029 case 2: /* lldt */ 3030 if (!PE(s) || VM86(s)) 3031 goto illegal_op; 3032 if (check_cpl0(s)) { 3033 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE); 3034 gen_ld_modrm(s, decode, MO_16); 3035 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3036 gen_helper_lldt(tcg_env, s->tmp2_i32); 3037 } 3038 break; 3039 case 1: /* str */ 3040 if (!PE(s) || VM86(s)) 3041 goto illegal_op; 3042 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3043 break; 3044 } 3045 gen_svm_check_intercept(s, SVM_EXIT_TR_READ); 3046 tcg_gen_ld32u_tl(s->T0, tcg_env, 3047 offsetof(CPUX86State, tr.selector)); 3048 ot = mod == 3 ? dflag : MO_16; 3049 gen_st_modrm(s, decode, ot); 3050 break; 3051 case 3: /* ltr */ 3052 if (!PE(s) || VM86(s)) 3053 goto illegal_op; 3054 if (check_cpl0(s)) { 3055 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE); 3056 gen_ld_modrm(s, decode, MO_16); 3057 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3058 gen_helper_ltr(tcg_env, s->tmp2_i32); 3059 } 3060 break; 3061 case 4: /* verr */ 3062 case 5: /* verw */ 3063 if (!PE(s) || VM86(s)) 3064 goto illegal_op; 3065 gen_ld_modrm(s, decode, MO_16); 3066 gen_update_cc_op(s); 3067 if (op == 4) { 3068 gen_helper_verr(tcg_env, s->T0); 3069 } else { 3070 gen_helper_verw(tcg_env, s->T0); 3071 } 3072 assume_cc_op(s, CC_OP_EFLAGS); 3073 break; 3074 default: 3075 goto illegal_op; 3076 } 3077 break; 3078 3079 case 0x101: 3080 switch (modrm) { 3081 CASE_MODRM_MEM_OP(0): /* sgdt */ 3082 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3083 break; 3084 } 3085 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ); 3086 gen_lea_modrm(s, decode); 3087 tcg_gen_ld32u_tl(s->T0, 3088 tcg_env, offsetof(CPUX86State, gdt.limit)); 3089 gen_op_st_v(s, MO_16, s->T0, s->A0); 3090 gen_add_A0_im(s, 2); 3091 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3092 /* 3093 * NB: Despite a confusing description in Intel CPU documentation, 3094 * all 32-bits are written regardless of operand size. 3095 */ 3096 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3097 break; 3098 3099 case 0xc8: /* monitor */ 3100 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3101 goto illegal_op; 3102 } 3103 gen_update_cc_op(s); 3104 gen_update_eip_cur(s); 3105 gen_lea_v_seg(s, cpu_regs[R_EAX], R_DS, s->override); 3106 gen_helper_monitor(tcg_env, s->A0); 3107 break; 3108 3109 case 0xc9: /* mwait */ 3110 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3111 goto illegal_op; 3112 } 3113 gen_update_cc_op(s); 3114 gen_update_eip_cur(s); 3115 gen_helper_mwait(tcg_env, cur_insn_len_i32(s)); 3116 s->base.is_jmp = DISAS_NORETURN; 3117 break; 3118 3119 case 0xca: /* clac */ 3120 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3121 || CPL(s) != 0) { 3122 goto illegal_op; 3123 } 3124 gen_reset_eflags(s, AC_MASK); 3125 s->base.is_jmp = DISAS_EOB_NEXT; 3126 break; 3127 3128 case 0xcb: /* stac */ 3129 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3130 || CPL(s) != 0) { 3131 goto illegal_op; 3132 } 3133 gen_set_eflags(s, AC_MASK); 3134 s->base.is_jmp = DISAS_EOB_NEXT; 3135 break; 3136 3137 CASE_MODRM_MEM_OP(1): /* sidt */ 3138 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3139 break; 3140 } 3141 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ); 3142 gen_lea_modrm(s, decode); 3143 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.limit)); 3144 gen_op_st_v(s, MO_16, s->T0, s->A0); 3145 gen_add_A0_im(s, 2); 3146 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3147 /* 3148 * NB: Despite a confusing description in Intel CPU documentation, 3149 * all 32-bits are written regardless of operand size. 3150 */ 3151 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3152 break; 3153 3154 case 0xd0: /* xgetbv */ 3155 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3156 || (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { 3157 goto illegal_op; 3158 } 3159 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3160 gen_helper_xgetbv(s->tmp1_i64, tcg_env, s->tmp2_i32); 3161 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3162 break; 3163 3164 case 0xd1: /* xsetbv */ 3165 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3166 || (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { 3167 goto illegal_op; 3168 } 3169 gen_svm_check_intercept(s, SVM_EXIT_XSETBV); 3170 if (!check_cpl0(s)) { 3171 break; 3172 } 3173 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3174 cpu_regs[R_EDX]); 3175 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3176 gen_helper_xsetbv(tcg_env, s->tmp2_i32, s->tmp1_i64); 3177 /* End TB because translation flags may change. */ 3178 s->base.is_jmp = DISAS_EOB_NEXT; 3179 break; 3180 3181 case 0xd8: /* VMRUN */ 3182 if (!SVME(s) || !PE(s)) { 3183 goto illegal_op; 3184 } 3185 if (!check_cpl0(s)) { 3186 break; 3187 } 3188 gen_update_cc_op(s); 3189 gen_update_eip_cur(s); 3190 /* 3191 * Reloads INHIBIT_IRQ mask as well as TF and RF with guest state. 3192 * The usual gen_eob() handling is performed on vmexit after 3193 * host state is reloaded. 3194 */ 3195 gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1), 3196 cur_insn_len_i32(s)); 3197 tcg_gen_exit_tb(NULL, 0); 3198 s->base.is_jmp = DISAS_NORETURN; 3199 break; 3200 3201 case 0xd9: /* VMMCALL */ 3202 if (!SVME(s)) { 3203 goto illegal_op; 3204 } 3205 gen_update_cc_op(s); 3206 gen_update_eip_cur(s); 3207 gen_helper_vmmcall(tcg_env); 3208 break; 3209 3210 case 0xda: /* VMLOAD */ 3211 if (!SVME(s) || !PE(s)) { 3212 goto illegal_op; 3213 } 3214 if (!check_cpl0(s)) { 3215 break; 3216 } 3217 gen_update_cc_op(s); 3218 gen_update_eip_cur(s); 3219 gen_helper_vmload(tcg_env, tcg_constant_i32(s->aflag - 1)); 3220 break; 3221 3222 case 0xdb: /* VMSAVE */ 3223 if (!SVME(s) || !PE(s)) { 3224 goto illegal_op; 3225 } 3226 if (!check_cpl0(s)) { 3227 break; 3228 } 3229 gen_update_cc_op(s); 3230 gen_update_eip_cur(s); 3231 gen_helper_vmsave(tcg_env, tcg_constant_i32(s->aflag - 1)); 3232 break; 3233 3234 case 0xdc: /* STGI */ 3235 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3236 || !PE(s)) { 3237 goto illegal_op; 3238 } 3239 if (!check_cpl0(s)) { 3240 break; 3241 } 3242 gen_update_cc_op(s); 3243 gen_helper_stgi(tcg_env); 3244 s->base.is_jmp = DISAS_EOB_NEXT; 3245 break; 3246 3247 case 0xdd: /* CLGI */ 3248 if (!SVME(s) || !PE(s)) { 3249 goto illegal_op; 3250 } 3251 if (!check_cpl0(s)) { 3252 break; 3253 } 3254 gen_update_cc_op(s); 3255 gen_update_eip_cur(s); 3256 gen_helper_clgi(tcg_env); 3257 break; 3258 3259 case 0xde: /* SKINIT */ 3260 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3261 || !PE(s)) { 3262 goto illegal_op; 3263 } 3264 gen_svm_check_intercept(s, SVM_EXIT_SKINIT); 3265 /* If not intercepted, not implemented -- raise #UD. */ 3266 goto illegal_op; 3267 3268 case 0xdf: /* INVLPGA */ 3269 if (!SVME(s) || !PE(s)) { 3270 goto illegal_op; 3271 } 3272 if (!check_cpl0(s)) { 3273 break; 3274 } 3275 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA); 3276 if (s->aflag == MO_64) { 3277 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 3278 } else { 3279 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]); 3280 } 3281 gen_helper_flush_page(tcg_env, s->A0); 3282 s->base.is_jmp = DISAS_EOB_NEXT; 3283 break; 3284 3285 CASE_MODRM_MEM_OP(2): /* lgdt */ 3286 if (!check_cpl0(s)) { 3287 break; 3288 } 3289 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE); 3290 gen_lea_modrm(s, decode); 3291 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3292 gen_add_A0_im(s, 2); 3293 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3294 if (dflag == MO_16) { 3295 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3296 } 3297 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3298 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, gdt.limit)); 3299 break; 3300 3301 CASE_MODRM_MEM_OP(3): /* lidt */ 3302 if (!check_cpl0(s)) { 3303 break; 3304 } 3305 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE); 3306 gen_lea_modrm(s, decode); 3307 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3308 gen_add_A0_im(s, 2); 3309 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3310 if (dflag == MO_16) { 3311 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3312 } 3313 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3314 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, idt.limit)); 3315 break; 3316 3317 CASE_MODRM_OP(4): /* smsw */ 3318 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3319 break; 3320 } 3321 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0); 3322 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, cr[0])); 3323 /* 3324 * In 32-bit mode, the higher 16 bits of the destination 3325 * register are undefined. In practice CR0[31:0] is stored 3326 * just like in 64-bit mode. 3327 */ 3328 mod = (modrm >> 6) & 3; 3329 ot = (mod != 3 ? MO_16 : s->dflag); 3330 gen_st_modrm(s, decode, ot); 3331 break; 3332 case 0xee: /* rdpkru */ 3333 if (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ)) { 3334 goto illegal_op; 3335 } 3336 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3337 gen_helper_rdpkru(s->tmp1_i64, tcg_env, s->tmp2_i32); 3338 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3339 break; 3340 case 0xef: /* wrpkru */ 3341 if (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ)) { 3342 goto illegal_op; 3343 } 3344 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3345 cpu_regs[R_EDX]); 3346 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3347 gen_helper_wrpkru(tcg_env, s->tmp2_i32, s->tmp1_i64); 3348 break; 3349 3350 CASE_MODRM_OP(6): /* lmsw */ 3351 if (!check_cpl0(s)) { 3352 break; 3353 } 3354 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 3355 gen_ld_modrm(s, decode, MO_16); 3356 /* 3357 * Only the 4 lower bits of CR0 are modified. 3358 * PE cannot be set to zero if already set to one. 3359 */ 3360 tcg_gen_ld_tl(s->T1, tcg_env, offsetof(CPUX86State, cr[0])); 3361 tcg_gen_andi_tl(s->T0, s->T0, 0xf); 3362 tcg_gen_andi_tl(s->T1, s->T1, ~0xe); 3363 tcg_gen_or_tl(s->T0, s->T0, s->T1); 3364 gen_helper_write_crN(tcg_env, tcg_constant_i32(0), s->T0); 3365 s->base.is_jmp = DISAS_EOB_NEXT; 3366 break; 3367 3368 CASE_MODRM_MEM_OP(7): /* invlpg */ 3369 if (!check_cpl0(s)) { 3370 break; 3371 } 3372 gen_svm_check_intercept(s, SVM_EXIT_INVLPG); 3373 gen_lea_modrm(s, decode); 3374 gen_helper_flush_page(tcg_env, s->A0); 3375 s->base.is_jmp = DISAS_EOB_NEXT; 3376 break; 3377 3378 case 0xf8: /* swapgs */ 3379 #ifdef TARGET_X86_64 3380 if (CODE64(s)) { 3381 if (check_cpl0(s)) { 3382 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]); 3383 tcg_gen_ld_tl(cpu_seg_base[R_GS], tcg_env, 3384 offsetof(CPUX86State, kernelgsbase)); 3385 tcg_gen_st_tl(s->T0, tcg_env, 3386 offsetof(CPUX86State, kernelgsbase)); 3387 } 3388 break; 3389 } 3390 #endif 3391 goto illegal_op; 3392 3393 case 0xf9: /* rdtscp */ 3394 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) { 3395 goto illegal_op; 3396 } 3397 gen_update_cc_op(s); 3398 gen_update_eip_cur(s); 3399 translator_io_start(&s->base); 3400 gen_helper_rdtsc(tcg_env); 3401 gen_helper_rdpid(s->T0, tcg_env); 3402 gen_op_mov_reg_v(s, dflag, R_ECX, s->T0); 3403 break; 3404 3405 default: 3406 goto illegal_op; 3407 } 3408 break; 3409 3410 case 0x11a: 3411 if (s->flags & HF_MPX_EN_MASK) { 3412 mod = (modrm >> 6) & 3; 3413 reg = ((modrm >> 3) & 7) | REX_R(s); 3414 if (prefixes & PREFIX_REPZ) { 3415 /* bndcl */ 3416 if (reg >= 4 3417 || s->aflag == MO_16) { 3418 goto illegal_op; 3419 } 3420 gen_bndck(s, decode, TCG_COND_LTU, cpu_bndl[reg]); 3421 } else if (prefixes & PREFIX_REPNZ) { 3422 /* bndcu */ 3423 if (reg >= 4 3424 || s->aflag == MO_16) { 3425 goto illegal_op; 3426 } 3427 TCGv_i64 notu = tcg_temp_new_i64(); 3428 tcg_gen_not_i64(notu, cpu_bndu[reg]); 3429 gen_bndck(s, decode, TCG_COND_GTU, notu); 3430 } else if (prefixes & PREFIX_DATA) { 3431 /* bndmov -- from reg/mem */ 3432 if (reg >= 4 || s->aflag == MO_16) { 3433 goto illegal_op; 3434 } 3435 if (mod == 3) { 3436 int reg2 = (modrm & 7) | REX_B(s); 3437 if (reg2 >= 4) { 3438 goto illegal_op; 3439 } 3440 if (s->flags & HF_MPX_IU_MASK) { 3441 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]); 3442 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]); 3443 } 3444 } else { 3445 gen_lea_modrm(s, decode); 3446 if (CODE64(s)) { 3447 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 3448 s->mem_index, MO_LEUQ); 3449 tcg_gen_addi_tl(s->A0, s->A0, 8); 3450 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 3451 s->mem_index, MO_LEUQ); 3452 } else { 3453 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 3454 s->mem_index, MO_LEUL); 3455 tcg_gen_addi_tl(s->A0, s->A0, 4); 3456 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 3457 s->mem_index, MO_LEUL); 3458 } 3459 /* bnd registers are now in-use */ 3460 gen_set_hflag(s, HF_MPX_IU_MASK); 3461 } 3462 } else if (mod != 3) { 3463 /* bndldx */ 3464 AddressParts a = decode->mem; 3465 if (reg >= 4 3466 || s->aflag == MO_16 3467 || a.base < -1) { 3468 goto illegal_op; 3469 } 3470 if (a.base >= 0) { 3471 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 3472 } else { 3473 tcg_gen_movi_tl(s->A0, 0); 3474 } 3475 gen_lea_v_seg(s, s->A0, a.def_seg, s->override); 3476 if (a.index >= 0) { 3477 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 3478 } else { 3479 tcg_gen_movi_tl(s->T0, 0); 3480 } 3481 if (CODE64(s)) { 3482 gen_helper_bndldx64(cpu_bndl[reg], tcg_env, s->A0, s->T0); 3483 tcg_gen_ld_i64(cpu_bndu[reg], tcg_env, 3484 offsetof(CPUX86State, mmx_t0.MMX_Q(0))); 3485 } else { 3486 gen_helper_bndldx32(cpu_bndu[reg], tcg_env, s->A0, s->T0); 3487 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]); 3488 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32); 3489 } 3490 gen_set_hflag(s, HF_MPX_IU_MASK); 3491 } 3492 } 3493 break; 3494 case 0x11b: 3495 if (s->flags & HF_MPX_EN_MASK) { 3496 mod = (modrm >> 6) & 3; 3497 reg = ((modrm >> 3) & 7) | REX_R(s); 3498 if (mod != 3 && (prefixes & PREFIX_REPZ)) { 3499 /* bndmk */ 3500 if (reg >= 4 3501 || s->aflag == MO_16) { 3502 goto illegal_op; 3503 } 3504 AddressParts a = decode->mem; 3505 if (a.base >= 0) { 3506 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]); 3507 if (!CODE64(s)) { 3508 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]); 3509 } 3510 } else if (a.base == -1) { 3511 /* no base register has lower bound of 0 */ 3512 tcg_gen_movi_i64(cpu_bndl[reg], 0); 3513 } else { 3514 /* rip-relative generates #ud */ 3515 goto illegal_op; 3516 } 3517 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, decode->mem, false)); 3518 if (!CODE64(s)) { 3519 tcg_gen_ext32u_tl(s->A0, s->A0); 3520 } 3521 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0); 3522 /* bnd registers are now in-use */ 3523 gen_set_hflag(s, HF_MPX_IU_MASK); 3524 break; 3525 } else if (prefixes & PREFIX_REPNZ) { 3526 /* bndcn */ 3527 if (reg >= 4 3528 || s->aflag == MO_16) { 3529 goto illegal_op; 3530 } 3531 gen_bndck(s, decode, TCG_COND_GTU, cpu_bndu[reg]); 3532 } else if (prefixes & PREFIX_DATA) { 3533 /* bndmov -- to reg/mem */ 3534 if (reg >= 4 || s->aflag == MO_16) { 3535 goto illegal_op; 3536 } 3537 if (mod == 3) { 3538 int reg2 = (modrm & 7) | REX_B(s); 3539 if (reg2 >= 4) { 3540 goto illegal_op; 3541 } 3542 if (s->flags & HF_MPX_IU_MASK) { 3543 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]); 3544 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]); 3545 } 3546 } else { 3547 gen_lea_modrm(s, decode); 3548 if (CODE64(s)) { 3549 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 3550 s->mem_index, MO_LEUQ); 3551 tcg_gen_addi_tl(s->A0, s->A0, 8); 3552 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 3553 s->mem_index, MO_LEUQ); 3554 } else { 3555 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 3556 s->mem_index, MO_LEUL); 3557 tcg_gen_addi_tl(s->A0, s->A0, 4); 3558 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 3559 s->mem_index, MO_LEUL); 3560 } 3561 } 3562 } else if (mod != 3) { 3563 /* bndstx */ 3564 AddressParts a = decode->mem; 3565 if (reg >= 4 3566 || s->aflag == MO_16 3567 || a.base < -1) { 3568 goto illegal_op; 3569 } 3570 if (a.base >= 0) { 3571 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 3572 } else { 3573 tcg_gen_movi_tl(s->A0, 0); 3574 } 3575 gen_lea_v_seg(s, s->A0, a.def_seg, s->override); 3576 if (a.index >= 0) { 3577 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 3578 } else { 3579 tcg_gen_movi_tl(s->T0, 0); 3580 } 3581 if (CODE64(s)) { 3582 gen_helper_bndstx64(tcg_env, s->A0, s->T0, 3583 cpu_bndl[reg], cpu_bndu[reg]); 3584 } else { 3585 gen_helper_bndstx32(tcg_env, s->A0, s->T0, 3586 cpu_bndl[reg], cpu_bndu[reg]); 3587 } 3588 } 3589 } 3590 break; 3591 default: 3592 g_assert_not_reached(); 3593 } 3594 return; 3595 illegal_op: 3596 gen_illegal_opcode(s); 3597 return; 3598 } 3599 3600 #include "decode-new.c.inc" 3601 3602 void tcg_x86_init(void) 3603 { 3604 static const char reg_names[CPU_NB_REGS][4] = { 3605 #ifdef TARGET_X86_64 3606 [R_EAX] = "rax", 3607 [R_EBX] = "rbx", 3608 [R_ECX] = "rcx", 3609 [R_EDX] = "rdx", 3610 [R_ESI] = "rsi", 3611 [R_EDI] = "rdi", 3612 [R_EBP] = "rbp", 3613 [R_ESP] = "rsp", 3614 [8] = "r8", 3615 [9] = "r9", 3616 [10] = "r10", 3617 [11] = "r11", 3618 [12] = "r12", 3619 [13] = "r13", 3620 [14] = "r14", 3621 [15] = "r15", 3622 #else 3623 [R_EAX] = "eax", 3624 [R_EBX] = "ebx", 3625 [R_ECX] = "ecx", 3626 [R_EDX] = "edx", 3627 [R_ESI] = "esi", 3628 [R_EDI] = "edi", 3629 [R_EBP] = "ebp", 3630 [R_ESP] = "esp", 3631 #endif 3632 }; 3633 static const char eip_name[] = { 3634 #ifdef TARGET_X86_64 3635 "rip" 3636 #else 3637 "eip" 3638 #endif 3639 }; 3640 static const char seg_base_names[6][8] = { 3641 [R_CS] = "cs_base", 3642 [R_DS] = "ds_base", 3643 [R_ES] = "es_base", 3644 [R_FS] = "fs_base", 3645 [R_GS] = "gs_base", 3646 [R_SS] = "ss_base", 3647 }; 3648 static const char bnd_regl_names[4][8] = { 3649 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb" 3650 }; 3651 static const char bnd_regu_names[4][8] = { 3652 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" 3653 }; 3654 int i; 3655 3656 cpu_cc_op = tcg_global_mem_new_i32(tcg_env, 3657 offsetof(CPUX86State, cc_op), "cc_op"); 3658 cpu_cc_dst = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_dst), 3659 "cc_dst"); 3660 cpu_cc_src = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src), 3661 "cc_src"); 3662 cpu_cc_src2 = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src2), 3663 "cc_src2"); 3664 cpu_eip = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, eip), eip_name); 3665 3666 for (i = 0; i < CPU_NB_REGS; ++i) { 3667 cpu_regs[i] = tcg_global_mem_new(tcg_env, 3668 offsetof(CPUX86State, regs[i]), 3669 reg_names[i]); 3670 } 3671 3672 for (i = 0; i < 6; ++i) { 3673 cpu_seg_base[i] 3674 = tcg_global_mem_new(tcg_env, 3675 offsetof(CPUX86State, segs[i].base), 3676 seg_base_names[i]); 3677 } 3678 3679 for (i = 0; i < 4; ++i) { 3680 cpu_bndl[i] 3681 = tcg_global_mem_new_i64(tcg_env, 3682 offsetof(CPUX86State, bnd_regs[i].lb), 3683 bnd_regl_names[i]); 3684 cpu_bndu[i] 3685 = tcg_global_mem_new_i64(tcg_env, 3686 offsetof(CPUX86State, bnd_regs[i].ub), 3687 bnd_regu_names[i]); 3688 } 3689 } 3690 3691 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 3692 { 3693 DisasContext *dc = container_of(dcbase, DisasContext, base); 3694 CPUX86State *env = cpu_env(cpu); 3695 uint32_t flags = dc->base.tb->flags; 3696 uint32_t cflags = tb_cflags(dc->base.tb); 3697 int cpl = (flags >> HF_CPL_SHIFT) & 3; 3698 int iopl = (flags >> IOPL_SHIFT) & 3; 3699 3700 dc->cs_base = dc->base.tb->cs_base; 3701 dc->pc_save = dc->base.pc_next; 3702 dc->flags = flags; 3703 #ifndef CONFIG_USER_ONLY 3704 dc->cpl = cpl; 3705 dc->iopl = iopl; 3706 #endif 3707 3708 /* We make some simplifying assumptions; validate they're correct. */ 3709 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); 3710 g_assert(CPL(dc) == cpl); 3711 g_assert(IOPL(dc) == iopl); 3712 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0)); 3713 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0)); 3714 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0)); 3715 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0)); 3716 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0)); 3717 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0)); 3718 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0)); 3719 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0)); 3720 3721 dc->cc_op = CC_OP_DYNAMIC; 3722 dc->cc_op_dirty = false; 3723 /* select memory access functions */ 3724 dc->mem_index = cpu_mmu_index(cpu, false); 3725 dc->cpuid_features = env->features[FEAT_1_EDX]; 3726 dc->cpuid_ext_features = env->features[FEAT_1_ECX]; 3727 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; 3728 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; 3729 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; 3730 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX]; 3731 dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX]; 3732 dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; 3733 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || 3734 (flags & (HF_RF_MASK | HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 3735 3736 dc->T0 = tcg_temp_new(); 3737 dc->T1 = tcg_temp_new(); 3738 dc->A0 = tcg_temp_new(); 3739 3740 dc->tmp0 = tcg_temp_new(); 3741 dc->tmp1_i64 = tcg_temp_new_i64(); 3742 dc->tmp2_i32 = tcg_temp_new_i32(); 3743 dc->tmp3_i32 = tcg_temp_new_i32(); 3744 dc->tmp4 = tcg_temp_new(); 3745 dc->cc_srcT = tcg_temp_new(); 3746 } 3747 3748 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) 3749 { 3750 } 3751 3752 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 3753 { 3754 DisasContext *dc = container_of(dcbase, DisasContext, base); 3755 target_ulong pc_arg = dc->base.pc_next; 3756 3757 dc->prev_insn_start = dc->base.insn_start; 3758 dc->prev_insn_end = tcg_last_op(); 3759 if (tb_cflags(dcbase->tb) & CF_PCREL) { 3760 pc_arg &= ~TARGET_PAGE_MASK; 3761 } 3762 tcg_gen_insn_start(pc_arg, dc->cc_op); 3763 } 3764 3765 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 3766 { 3767 DisasContext *dc = container_of(dcbase, DisasContext, base); 3768 bool orig_cc_op_dirty = dc->cc_op_dirty; 3769 CCOp orig_cc_op = dc->cc_op; 3770 target_ulong orig_pc_save = dc->pc_save; 3771 3772 #ifdef TARGET_VSYSCALL_PAGE 3773 /* 3774 * Detect entry into the vsyscall page and invoke the syscall. 3775 */ 3776 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) { 3777 gen_exception(dc, EXCP_VSYSCALL); 3778 dc->base.pc_next = dc->pc + 1; 3779 return; 3780 } 3781 #endif 3782 3783 switch (sigsetjmp(dc->jmpbuf, 0)) { 3784 case 0: 3785 disas_insn(dc, cpu); 3786 break; 3787 case 1: 3788 gen_exception_gpf(dc); 3789 break; 3790 case 2: 3791 /* Restore state that may affect the next instruction. */ 3792 dc->pc = dc->base.pc_next; 3793 assert(dc->cc_op_dirty == orig_cc_op_dirty); 3794 assert(dc->cc_op == orig_cc_op); 3795 assert(dc->pc_save == orig_pc_save); 3796 dc->base.num_insns--; 3797 tcg_remove_ops_after(dc->prev_insn_end); 3798 dc->base.insn_start = dc->prev_insn_start; 3799 dc->base.is_jmp = DISAS_TOO_MANY; 3800 return; 3801 default: 3802 g_assert_not_reached(); 3803 } 3804 3805 /* 3806 * Instruction decoding completed (possibly with #GP if the 3807 * 15-byte boundary was exceeded). 3808 */ 3809 dc->base.pc_next = dc->pc; 3810 if (dc->base.is_jmp == DISAS_NEXT) { 3811 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) { 3812 /* 3813 * If single step mode, we generate only one instruction and 3814 * generate an exception. 3815 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 3816 * the flag and abort the translation to give the irqs a 3817 * chance to happen. 3818 */ 3819 dc->base.is_jmp = DISAS_EOB_NEXT; 3820 } else if (!translator_is_same_page(&dc->base, dc->base.pc_next)) { 3821 dc->base.is_jmp = DISAS_TOO_MANY; 3822 } 3823 } 3824 } 3825 3826 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 3827 { 3828 DisasContext *dc = container_of(dcbase, DisasContext, base); 3829 3830 switch (dc->base.is_jmp) { 3831 case DISAS_NORETURN: 3832 /* 3833 * Most instructions should not use DISAS_NORETURN, as that suppresses 3834 * the handling of hflags normally done by gen_eob(). We can 3835 * get here: 3836 * - for exception and interrupts 3837 * - for jump optimization (which is disabled by INHIBIT_IRQ/RF/TF) 3838 * - for VMRUN because RF/TF handling for the host is done after vmexit, 3839 * and INHIBIT_IRQ is loaded from the VMCB 3840 * - for HLT/PAUSE/MWAIT to exit the main loop with specific EXCP_* values; 3841 * the helpers handle themselves the tasks normally done by gen_eob(). 3842 */ 3843 break; 3844 case DISAS_TOO_MANY: 3845 gen_update_cc_op(dc); 3846 gen_jmp_rel_csize(dc, 0, 0); 3847 break; 3848 case DISAS_EOB_NEXT: 3849 case DISAS_EOB_INHIBIT_IRQ: 3850 assert(dc->base.pc_next == dc->pc); 3851 gen_update_eip_cur(dc); 3852 /* fall through */ 3853 case DISAS_EOB_ONLY: 3854 case DISAS_EOB_RECHECK_TF: 3855 case DISAS_JUMP: 3856 gen_eob(dc, dc->base.is_jmp); 3857 break; 3858 default: 3859 g_assert_not_reached(); 3860 } 3861 } 3862 3863 static const TranslatorOps i386_tr_ops = { 3864 .init_disas_context = i386_tr_init_disas_context, 3865 .tb_start = i386_tr_tb_start, 3866 .insn_start = i386_tr_insn_start, 3867 .translate_insn = i386_tr_translate_insn, 3868 .tb_stop = i386_tr_tb_stop, 3869 }; 3870 3871 void x86_translate_code(CPUState *cpu, TranslationBlock *tb, 3872 int *max_insns, vaddr pc, void *host_pc) 3873 { 3874 DisasContext dc; 3875 3876 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); 3877 } 3878