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