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_setcc1(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_setcc1(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_jcc1_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_jcc1(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 /* Generate jumps to current or next instruction */ 1314 static void gen_repz(DisasContext *s, MemOp ot, 1315 void (*fn)(DisasContext *s, MemOp ot)) 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 /* 1322 * A loop would cause two single step exceptions if ECX = 1 1323 * before rep string_insn 1324 */ 1325 if (s->repz_opt) { 1326 gen_op_jz_ecx(s, l2); 1327 } 1328 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1329 } 1330 1331 static void gen_repz_nz(DisasContext *s, MemOp ot, 1332 void (*fn)(DisasContext *s, MemOp ot)) 1333 { 1334 TCGLabel *l2; 1335 int nz = (s->prefix & PREFIX_REPNZ) ? 1 : 0; 1336 1337 l2 = gen_jz_ecx_string(s); 1338 fn(s, ot); 1339 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 1340 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); 1341 if (s->repz_opt) { 1342 gen_op_jz_ecx(s, l2); 1343 } 1344 /* 1345 * Only one iteration is done at a time, so the translation 1346 * block ends unconditionally after this instruction and there 1347 * is no control flow junction - no need to set CC_OP_DYNAMIC. 1348 */ 1349 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1350 } 1351 1352 static void gen_helper_fp_arith_ST0_FT0(int op) 1353 { 1354 switch (op) { 1355 case 0: 1356 gen_helper_fadd_ST0_FT0(tcg_env); 1357 break; 1358 case 1: 1359 gen_helper_fmul_ST0_FT0(tcg_env); 1360 break; 1361 case 2: 1362 gen_helper_fcom_ST0_FT0(tcg_env); 1363 break; 1364 case 3: 1365 gen_helper_fcom_ST0_FT0(tcg_env); 1366 break; 1367 case 4: 1368 gen_helper_fsub_ST0_FT0(tcg_env); 1369 break; 1370 case 5: 1371 gen_helper_fsubr_ST0_FT0(tcg_env); 1372 break; 1373 case 6: 1374 gen_helper_fdiv_ST0_FT0(tcg_env); 1375 break; 1376 case 7: 1377 gen_helper_fdivr_ST0_FT0(tcg_env); 1378 break; 1379 } 1380 } 1381 1382 /* NOTE the exception in "r" op ordering */ 1383 static void gen_helper_fp_arith_STN_ST0(int op, int opreg) 1384 { 1385 TCGv_i32 tmp = tcg_constant_i32(opreg); 1386 switch (op) { 1387 case 0: 1388 gen_helper_fadd_STN_ST0(tcg_env, tmp); 1389 break; 1390 case 1: 1391 gen_helper_fmul_STN_ST0(tcg_env, tmp); 1392 break; 1393 case 4: 1394 gen_helper_fsubr_STN_ST0(tcg_env, tmp); 1395 break; 1396 case 5: 1397 gen_helper_fsub_STN_ST0(tcg_env, tmp); 1398 break; 1399 case 6: 1400 gen_helper_fdivr_STN_ST0(tcg_env, tmp); 1401 break; 1402 case 7: 1403 gen_helper_fdiv_STN_ST0(tcg_env, tmp); 1404 break; 1405 } 1406 } 1407 1408 static void gen_exception(DisasContext *s, int trapno) 1409 { 1410 gen_update_cc_op(s); 1411 gen_update_eip_cur(s); 1412 gen_helper_raise_exception(tcg_env, tcg_constant_i32(trapno)); 1413 s->base.is_jmp = DISAS_NORETURN; 1414 } 1415 1416 /* Generate #UD for the current instruction. The assumption here is that 1417 the instruction is known, but it isn't allowed in the current cpu mode. */ 1418 static void gen_illegal_opcode(DisasContext *s) 1419 { 1420 gen_exception(s, EXCP06_ILLOP); 1421 } 1422 1423 /* Generate #GP for the current instruction. */ 1424 static void gen_exception_gpf(DisasContext *s) 1425 { 1426 gen_exception(s, EXCP0D_GPF); 1427 } 1428 1429 /* Check for cpl == 0; if not, raise #GP and return false. */ 1430 static bool check_cpl0(DisasContext *s) 1431 { 1432 if (CPL(s) == 0) { 1433 return true; 1434 } 1435 gen_exception_gpf(s); 1436 return false; 1437 } 1438 1439 /* XXX: add faster immediate case */ 1440 static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, 1441 bool is_right, TCGv count) 1442 { 1443 target_ulong mask = (ot == MO_64 ? 63 : 31); 1444 1445 switch (ot) { 1446 case MO_16: 1447 /* Note: we implement the Intel behaviour for shift count > 16. 1448 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A 1449 portion by constructing it as a 32-bit value. */ 1450 if (is_right) { 1451 tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16); 1452 tcg_gen_mov_tl(s->T1, s->T0); 1453 tcg_gen_mov_tl(s->T0, s->tmp0); 1454 } else { 1455 tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16); 1456 } 1457 /* 1458 * If TARGET_X86_64 defined then fall through into MO_32 case, 1459 * otherwise fall through default case. 1460 */ 1461 case MO_32: 1462 #ifdef TARGET_X86_64 1463 /* Concatenate the two 32-bit values and use a 64-bit shift. */ 1464 tcg_gen_subi_tl(s->tmp0, count, 1); 1465 if (is_right) { 1466 tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1); 1467 tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0); 1468 tcg_gen_shr_i64(s->T0, s->T0, count); 1469 } else { 1470 tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0); 1471 tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0); 1472 tcg_gen_shl_i64(s->T0, s->T0, count); 1473 tcg_gen_shri_i64(s->tmp0, s->tmp0, 32); 1474 tcg_gen_shri_i64(s->T0, s->T0, 32); 1475 } 1476 break; 1477 #endif 1478 default: 1479 tcg_gen_subi_tl(s->tmp0, count, 1); 1480 if (is_right) { 1481 tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0); 1482 1483 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1484 tcg_gen_shr_tl(s->T0, s->T0, count); 1485 tcg_gen_shl_tl(s->T1, s->T1, s->tmp4); 1486 } else { 1487 tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0); 1488 if (ot == MO_16) { 1489 /* Only needed if count > 16, for Intel behaviour. */ 1490 tcg_gen_subfi_tl(s->tmp4, 33, count); 1491 tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4); 1492 tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4); 1493 } 1494 1495 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1496 tcg_gen_shl_tl(s->T0, s->T0, count); 1497 tcg_gen_shr_tl(s->T1, s->T1, s->tmp4); 1498 } 1499 tcg_gen_movi_tl(s->tmp4, 0); 1500 tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4, 1501 s->tmp4, s->T1); 1502 tcg_gen_or_tl(s->T0, s->T0, s->T1); 1503 break; 1504 } 1505 } 1506 1507 #define X86_MAX_INSN_LENGTH 15 1508 1509 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes) 1510 { 1511 uint64_t pc = s->pc; 1512 1513 /* This is a subsequent insn that crosses a page boundary. */ 1514 if (s->base.num_insns > 1 && 1515 !translator_is_same_page(&s->base, s->pc + num_bytes - 1)) { 1516 siglongjmp(s->jmpbuf, 2); 1517 } 1518 1519 s->pc += num_bytes; 1520 if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) { 1521 /* If the instruction's 16th byte is on a different page than the 1st, a 1522 * page fault on the second page wins over the general protection fault 1523 * caused by the instruction being too long. 1524 * This can happen even if the operand is only one byte long! 1525 */ 1526 if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) { 1527 (void)translator_ldub(env, &s->base, 1528 (s->pc - 1) & TARGET_PAGE_MASK); 1529 } 1530 siglongjmp(s->jmpbuf, 1); 1531 } 1532 1533 return pc; 1534 } 1535 1536 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s) 1537 { 1538 return translator_ldub(env, &s->base, advance_pc(env, s, 1)); 1539 } 1540 1541 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s) 1542 { 1543 return translator_lduw(env, &s->base, advance_pc(env, s, 2)); 1544 } 1545 1546 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s) 1547 { 1548 return translator_ldl(env, &s->base, advance_pc(env, s, 4)); 1549 } 1550 1551 #ifdef TARGET_X86_64 1552 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s) 1553 { 1554 return translator_ldq(env, &s->base, advance_pc(env, s, 8)); 1555 } 1556 #endif 1557 1558 /* Decompose an address. */ 1559 1560 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s, 1561 int modrm, bool is_vsib) 1562 { 1563 int def_seg, base, index, scale, mod, rm; 1564 target_long disp; 1565 bool havesib; 1566 1567 def_seg = R_DS; 1568 index = -1; 1569 scale = 0; 1570 disp = 0; 1571 1572 mod = (modrm >> 6) & 3; 1573 rm = modrm & 7; 1574 base = rm | REX_B(s); 1575 1576 if (mod == 3) { 1577 /* Normally filtered out earlier, but including this path 1578 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */ 1579 goto done; 1580 } 1581 1582 switch (s->aflag) { 1583 case MO_64: 1584 case MO_32: 1585 havesib = 0; 1586 if (rm == 4) { 1587 int code = x86_ldub_code(env, s); 1588 scale = (code >> 6) & 3; 1589 index = ((code >> 3) & 7) | REX_X(s); 1590 if (index == 4 && !is_vsib) { 1591 index = -1; /* no index */ 1592 } 1593 base = (code & 7) | REX_B(s); 1594 havesib = 1; 1595 } 1596 1597 switch (mod) { 1598 case 0: 1599 if ((base & 7) == 5) { 1600 base = -1; 1601 disp = (int32_t)x86_ldl_code(env, s); 1602 if (CODE64(s) && !havesib) { 1603 base = -2; 1604 disp += s->pc + s->rip_offset; 1605 } 1606 } 1607 break; 1608 case 1: 1609 disp = (int8_t)x86_ldub_code(env, s); 1610 break; 1611 default: 1612 case 2: 1613 disp = (int32_t)x86_ldl_code(env, s); 1614 break; 1615 } 1616 1617 /* For correct popl handling with esp. */ 1618 if (base == R_ESP && s->popl_esp_hack) { 1619 disp += s->popl_esp_hack; 1620 } 1621 if (base == R_EBP || base == R_ESP) { 1622 def_seg = R_SS; 1623 } 1624 break; 1625 1626 case MO_16: 1627 if (mod == 0) { 1628 if (rm == 6) { 1629 base = -1; 1630 disp = x86_lduw_code(env, s); 1631 break; 1632 } 1633 } else if (mod == 1) { 1634 disp = (int8_t)x86_ldub_code(env, s); 1635 } else { 1636 disp = (int16_t)x86_lduw_code(env, s); 1637 } 1638 1639 switch (rm) { 1640 case 0: 1641 base = R_EBX; 1642 index = R_ESI; 1643 break; 1644 case 1: 1645 base = R_EBX; 1646 index = R_EDI; 1647 break; 1648 case 2: 1649 base = R_EBP; 1650 index = R_ESI; 1651 def_seg = R_SS; 1652 break; 1653 case 3: 1654 base = R_EBP; 1655 index = R_EDI; 1656 def_seg = R_SS; 1657 break; 1658 case 4: 1659 base = R_ESI; 1660 break; 1661 case 5: 1662 base = R_EDI; 1663 break; 1664 case 6: 1665 base = R_EBP; 1666 def_seg = R_SS; 1667 break; 1668 default: 1669 case 7: 1670 base = R_EBX; 1671 break; 1672 } 1673 break; 1674 1675 default: 1676 g_assert_not_reached(); 1677 } 1678 1679 done: 1680 return (AddressParts){ def_seg, base, index, scale, disp }; 1681 } 1682 1683 /* Compute the address, with a minimum number of TCG ops. */ 1684 static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib) 1685 { 1686 TCGv ea = NULL; 1687 1688 if (a.index >= 0 && !is_vsib) { 1689 if (a.scale == 0) { 1690 ea = cpu_regs[a.index]; 1691 } else { 1692 tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale); 1693 ea = s->A0; 1694 } 1695 if (a.base >= 0) { 1696 tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]); 1697 ea = s->A0; 1698 } 1699 } else if (a.base >= 0) { 1700 ea = cpu_regs[a.base]; 1701 } 1702 if (!ea) { 1703 if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) { 1704 /* With cpu_eip ~= pc_save, the expression is pc-relative. */ 1705 tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save); 1706 } else { 1707 tcg_gen_movi_tl(s->A0, a.disp); 1708 } 1709 ea = s->A0; 1710 } else if (a.disp != 0) { 1711 tcg_gen_addi_tl(s->A0, ea, a.disp); 1712 ea = s->A0; 1713 } 1714 1715 return ea; 1716 } 1717 1718 /* Used for BNDCL, BNDCU, BNDCN. */ 1719 static void gen_bndck(DisasContext *s, X86DecodedInsn *decode, 1720 TCGCond cond, TCGv_i64 bndv) 1721 { 1722 TCGv ea = gen_lea_modrm_1(s, decode->mem, false); 1723 1724 tcg_gen_extu_tl_i64(s->tmp1_i64, ea); 1725 if (!CODE64(s)) { 1726 tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64); 1727 } 1728 tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv); 1729 tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64); 1730 gen_helper_bndck(tcg_env, s->tmp2_i32); 1731 } 1732 1733 /* generate modrm load of memory or register. */ 1734 static void gen_ld_modrm(DisasContext *s, X86DecodedInsn *decode, MemOp ot) 1735 { 1736 int modrm = s->modrm; 1737 int mod, rm; 1738 1739 mod = (modrm >> 6) & 3; 1740 rm = (modrm & 7) | REX_B(s); 1741 if (mod == 3) { 1742 gen_op_mov_v_reg(s, ot, s->T0, rm); 1743 } else { 1744 gen_lea_modrm(s, decode); 1745 gen_op_ld_v(s, ot, s->T0, s->A0); 1746 } 1747 } 1748 1749 /* generate modrm store of memory or register. */ 1750 static void gen_st_modrm(DisasContext *s, X86DecodedInsn *decode, MemOp ot) 1751 { 1752 int modrm = s->modrm; 1753 int mod, rm; 1754 1755 mod = (modrm >> 6) & 3; 1756 rm = (modrm & 7) | REX_B(s); 1757 if (mod == 3) { 1758 gen_op_mov_reg_v(s, ot, rm, s->T0); 1759 } else { 1760 gen_lea_modrm(s, decode); 1761 gen_op_st_v(s, ot, s->T0, s->A0); 1762 } 1763 } 1764 1765 static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot) 1766 { 1767 target_ulong ret; 1768 1769 switch (ot) { 1770 case MO_8: 1771 ret = x86_ldub_code(env, s); 1772 break; 1773 case MO_16: 1774 ret = x86_lduw_code(env, s); 1775 break; 1776 case MO_32: 1777 ret = x86_ldl_code(env, s); 1778 break; 1779 #ifdef TARGET_X86_64 1780 case MO_64: 1781 ret = x86_ldq_code(env, s); 1782 break; 1783 #endif 1784 default: 1785 g_assert_not_reached(); 1786 } 1787 return ret; 1788 } 1789 1790 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot) 1791 { 1792 uint32_t ret; 1793 1794 switch (ot) { 1795 case MO_8: 1796 ret = x86_ldub_code(env, s); 1797 break; 1798 case MO_16: 1799 ret = x86_lduw_code(env, s); 1800 break; 1801 case MO_32: 1802 #ifdef TARGET_X86_64 1803 case MO_64: 1804 #endif 1805 ret = x86_ldl_code(env, s); 1806 break; 1807 default: 1808 g_assert_not_reached(); 1809 } 1810 return ret; 1811 } 1812 1813 static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot) 1814 { 1815 target_long ret; 1816 1817 switch (ot) { 1818 case MO_8: 1819 ret = (int8_t) x86_ldub_code(env, s); 1820 break; 1821 case MO_16: 1822 ret = (int16_t) x86_lduw_code(env, s); 1823 break; 1824 case MO_32: 1825 ret = (int32_t) x86_ldl_code(env, s); 1826 break; 1827 #ifdef TARGET_X86_64 1828 case MO_64: 1829 ret = x86_ldq_code(env, s); 1830 break; 1831 #endif 1832 default: 1833 g_assert_not_reached(); 1834 } 1835 return ret; 1836 } 1837 1838 static void gen_conditional_jump_labels(DisasContext *s, target_long diff, 1839 TCGLabel *not_taken, TCGLabel *taken) 1840 { 1841 if (not_taken) { 1842 gen_set_label(not_taken); 1843 } 1844 gen_jmp_rel_csize(s, 0, 1); 1845 1846 gen_set_label(taken); 1847 gen_jmp_rel(s, s->dflag, diff, 0); 1848 } 1849 1850 static void gen_jcc(DisasContext *s, int b, int diff) 1851 { 1852 TCGLabel *l1 = gen_new_label(); 1853 1854 gen_jcc1(s, b, l1); 1855 gen_conditional_jump_labels(s, diff, NULL, l1); 1856 } 1857 1858 static void gen_cmovcc1(DisasContext *s, int b, TCGv dest, TCGv src) 1859 { 1860 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1861 1862 if (!cc.use_reg2) { 1863 cc.reg2 = tcg_constant_tl(cc.imm); 1864 } 1865 1866 tcg_gen_movcond_tl(cc.cond, dest, cc.reg, cc.reg2, src, dest); 1867 } 1868 1869 static void gen_op_movl_seg_real(DisasContext *s, X86Seg seg_reg, TCGv seg) 1870 { 1871 TCGv selector = tcg_temp_new(); 1872 tcg_gen_ext16u_tl(selector, seg); 1873 tcg_gen_st32_tl(selector, tcg_env, 1874 offsetof(CPUX86State,segs[seg_reg].selector)); 1875 tcg_gen_shli_tl(cpu_seg_base[seg_reg], selector, 4); 1876 } 1877 1878 /* move SRC to seg_reg and compute if the CPU state may change. Never 1879 call this function with seg_reg == R_CS */ 1880 static void gen_movl_seg(DisasContext *s, X86Seg seg_reg, TCGv src) 1881 { 1882 if (PE(s) && !VM86(s)) { 1883 tcg_gen_trunc_tl_i32(s->tmp2_i32, src); 1884 gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32); 1885 /* abort translation because the addseg value may change or 1886 because ss32 may change. For R_SS, translation must always 1887 stop as a special handling must be done to disable hardware 1888 interrupts for the next instruction */ 1889 if (seg_reg == R_SS) { 1890 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 1891 } else if (CODE32(s) && seg_reg < R_FS) { 1892 s->base.is_jmp = DISAS_EOB_NEXT; 1893 } 1894 } else { 1895 gen_op_movl_seg_real(s, seg_reg, src); 1896 if (seg_reg == R_SS) { 1897 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 1898 } 1899 } 1900 } 1901 1902 static void gen_far_call(DisasContext *s) 1903 { 1904 TCGv_i32 new_cs = tcg_temp_new_i32(); 1905 tcg_gen_trunc_tl_i32(new_cs, s->T1); 1906 if (PE(s) && !VM86(s)) { 1907 gen_helper_lcall_protected(tcg_env, new_cs, s->T0, 1908 tcg_constant_i32(s->dflag - 1), 1909 eip_next_tl(s)); 1910 } else { 1911 TCGv_i32 new_eip = tcg_temp_new_i32(); 1912 tcg_gen_trunc_tl_i32(new_eip, s->T0); 1913 gen_helper_lcall_real(tcg_env, new_cs, new_eip, 1914 tcg_constant_i32(s->dflag - 1), 1915 eip_next_i32(s)); 1916 } 1917 s->base.is_jmp = DISAS_JUMP; 1918 } 1919 1920 static void gen_far_jmp(DisasContext *s) 1921 { 1922 if (PE(s) && !VM86(s)) { 1923 TCGv_i32 new_cs = tcg_temp_new_i32(); 1924 tcg_gen_trunc_tl_i32(new_cs, s->T1); 1925 gen_helper_ljmp_protected(tcg_env, new_cs, s->T0, 1926 eip_next_tl(s)); 1927 } else { 1928 gen_op_movl_seg_real(s, R_CS, s->T1); 1929 gen_op_jmp_v(s, s->T0); 1930 } 1931 s->base.is_jmp = DISAS_JUMP; 1932 } 1933 1934 static void gen_svm_check_intercept(DisasContext *s, uint32_t type) 1935 { 1936 /* no SVM activated; fast case */ 1937 if (likely(!GUEST(s))) { 1938 return; 1939 } 1940 gen_helper_svm_check_intercept(tcg_env, tcg_constant_i32(type)); 1941 } 1942 1943 static inline void gen_stack_update(DisasContext *s, int addend) 1944 { 1945 gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend); 1946 } 1947 1948 static void gen_lea_ss_ofs(DisasContext *s, TCGv dest, TCGv src, target_ulong offset) 1949 { 1950 if (offset) { 1951 tcg_gen_addi_tl(dest, src, offset); 1952 src = dest; 1953 } 1954 gen_lea_v_seg_dest(s, mo_stacksize(s), dest, src, R_SS, -1); 1955 } 1956 1957 /* Generate a push. It depends on ss32, addseg and dflag. */ 1958 static void gen_push_v(DisasContext *s, TCGv val) 1959 { 1960 MemOp d_ot = mo_pushpop(s, s->dflag); 1961 MemOp a_ot = mo_stacksize(s); 1962 int size = 1 << d_ot; 1963 TCGv new_esp = tcg_temp_new(); 1964 1965 tcg_gen_subi_tl(new_esp, cpu_regs[R_ESP], size); 1966 1967 /* Now reduce the value to the address size and apply SS base. */ 1968 gen_lea_ss_ofs(s, s->A0, new_esp, 0); 1969 gen_op_st_v(s, d_ot, val, s->A0); 1970 gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp); 1971 } 1972 1973 /* two step pop is necessary for precise exceptions */ 1974 static MemOp gen_pop_T0(DisasContext *s) 1975 { 1976 MemOp d_ot = mo_pushpop(s, s->dflag); 1977 1978 gen_lea_ss_ofs(s, s->T0, cpu_regs[R_ESP], 0); 1979 gen_op_ld_v(s, d_ot, s->T0, s->T0); 1980 1981 return d_ot; 1982 } 1983 1984 static inline void gen_pop_update(DisasContext *s, MemOp ot) 1985 { 1986 gen_stack_update(s, 1 << ot); 1987 } 1988 1989 static void gen_pusha(DisasContext *s) 1990 { 1991 MemOp d_ot = s->dflag; 1992 int size = 1 << d_ot; 1993 int i; 1994 1995 for (i = 0; i < 8; i++) { 1996 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], (i - 8) * size); 1997 gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0); 1998 } 1999 2000 gen_stack_update(s, -8 * size); 2001 } 2002 2003 static void gen_popa(DisasContext *s) 2004 { 2005 MemOp d_ot = s->dflag; 2006 int size = 1 << d_ot; 2007 int i; 2008 2009 for (i = 0; i < 8; i++) { 2010 /* ESP is not reloaded */ 2011 if (7 - i == R_ESP) { 2012 continue; 2013 } 2014 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], i * size); 2015 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2016 gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0); 2017 } 2018 2019 gen_stack_update(s, 8 * size); 2020 } 2021 2022 static void gen_enter(DisasContext *s, int esp_addend, int level) 2023 { 2024 MemOp d_ot = mo_pushpop(s, s->dflag); 2025 MemOp a_ot = mo_stacksize(s); 2026 int size = 1 << d_ot; 2027 2028 /* Push BP; compute FrameTemp into T1. */ 2029 tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size); 2030 gen_lea_ss_ofs(s, s->A0, s->T1, 0); 2031 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0); 2032 2033 level &= 31; 2034 if (level != 0) { 2035 int i; 2036 2037 /* Copy level-1 pointers from the previous frame. */ 2038 for (i = 1; i < level; ++i) { 2039 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], -size * i); 2040 gen_op_ld_v(s, d_ot, s->tmp0, s->A0); 2041 2042 gen_lea_ss_ofs(s, s->A0, s->T1, -size * i); 2043 gen_op_st_v(s, d_ot, s->tmp0, s->A0); 2044 } 2045 2046 /* Push the current FrameTemp as the last level. */ 2047 gen_lea_ss_ofs(s, s->A0, s->T1, -size * level); 2048 gen_op_st_v(s, d_ot, s->T1, s->A0); 2049 } 2050 2051 /* Copy the FrameTemp value to EBP. */ 2052 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T1); 2053 2054 /* Compute the final value of ESP. */ 2055 tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level); 2056 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2057 } 2058 2059 static void gen_leave(DisasContext *s) 2060 { 2061 MemOp d_ot = mo_pushpop(s, s->dflag); 2062 MemOp a_ot = mo_stacksize(s); 2063 2064 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], 0); 2065 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2066 2067 tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot); 2068 2069 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0); 2070 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2071 } 2072 2073 /* Similarly, except that the assumption here is that we don't decode 2074 the instruction at all -- either a missing opcode, an unimplemented 2075 feature, or just a bogus instruction stream. */ 2076 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) 2077 { 2078 gen_illegal_opcode(s); 2079 2080 if (qemu_loglevel_mask(LOG_UNIMP)) { 2081 FILE *logfile = qemu_log_trylock(); 2082 if (logfile) { 2083 target_ulong pc = s->base.pc_next, end = s->pc; 2084 2085 fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc); 2086 for (; pc < end; ++pc) { 2087 fprintf(logfile, " %02x", translator_ldub(env, &s->base, pc)); 2088 } 2089 fprintf(logfile, "\n"); 2090 qemu_log_unlock(logfile); 2091 } 2092 } 2093 } 2094 2095 /* an interrupt is different from an exception because of the 2096 privilege checks */ 2097 static void gen_interrupt(DisasContext *s, uint8_t intno) 2098 { 2099 gen_update_cc_op(s); 2100 gen_update_eip_cur(s); 2101 gen_helper_raise_interrupt(tcg_env, tcg_constant_i32(intno), 2102 cur_insn_len_i32(s)); 2103 s->base.is_jmp = DISAS_NORETURN; 2104 } 2105 2106 static void gen_set_hflag(DisasContext *s, uint32_t mask) 2107 { 2108 if ((s->flags & mask) == 0) { 2109 TCGv_i32 t = tcg_temp_new_i32(); 2110 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2111 tcg_gen_ori_i32(t, t, mask); 2112 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2113 s->flags |= mask; 2114 } 2115 } 2116 2117 static void gen_reset_hflag(DisasContext *s, uint32_t mask) 2118 { 2119 if (s->flags & mask) { 2120 TCGv_i32 t = tcg_temp_new_i32(); 2121 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2122 tcg_gen_andi_i32(t, t, ~mask); 2123 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2124 s->flags &= ~mask; 2125 } 2126 } 2127 2128 static void gen_set_eflags(DisasContext *s, target_ulong mask) 2129 { 2130 TCGv t = tcg_temp_new(); 2131 2132 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2133 tcg_gen_ori_tl(t, t, mask); 2134 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2135 } 2136 2137 static void gen_reset_eflags(DisasContext *s, target_ulong mask) 2138 { 2139 TCGv t = tcg_temp_new(); 2140 2141 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2142 tcg_gen_andi_tl(t, t, ~mask); 2143 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2144 } 2145 2146 /* Clear BND registers during legacy branches. */ 2147 static void gen_bnd_jmp(DisasContext *s) 2148 { 2149 /* Clear the registers only if BND prefix is missing, MPX is enabled, 2150 and if the BNDREGs are known to be in use (non-zero) already. 2151 The helper itself will check BNDPRESERVE at runtime. */ 2152 if ((s->prefix & PREFIX_REPNZ) == 0 2153 && (s->flags & HF_MPX_EN_MASK) != 0 2154 && (s->flags & HF_MPX_IU_MASK) != 0) { 2155 gen_helper_bnd_jmp(tcg_env); 2156 } 2157 } 2158 2159 /* 2160 * Generate an end of block, including common tasks such as generating 2161 * single step traps, resetting the RF flag, and handling the interrupt 2162 * shadow. 2163 */ 2164 static void 2165 gen_eob(DisasContext *s, int mode) 2166 { 2167 bool inhibit_reset; 2168 2169 gen_update_cc_op(s); 2170 2171 /* If several instructions disable interrupts, only the first does it. */ 2172 inhibit_reset = false; 2173 if (s->flags & HF_INHIBIT_IRQ_MASK) { 2174 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); 2175 inhibit_reset = true; 2176 } else if (mode == DISAS_EOB_INHIBIT_IRQ) { 2177 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); 2178 } 2179 2180 if (s->base.tb->flags & HF_RF_MASK) { 2181 gen_reset_eflags(s, RF_MASK); 2182 } 2183 if (mode == DISAS_EOB_RECHECK_TF) { 2184 gen_helper_rechecking_single_step(tcg_env); 2185 tcg_gen_exit_tb(NULL, 0); 2186 } else if ((s->flags & HF_TF_MASK) && mode != DISAS_EOB_INHIBIT_IRQ) { 2187 gen_helper_single_step(tcg_env); 2188 } else if (mode == DISAS_JUMP && 2189 /* give irqs a chance to happen */ 2190 !inhibit_reset) { 2191 tcg_gen_lookup_and_goto_ptr(); 2192 } else { 2193 tcg_gen_exit_tb(NULL, 0); 2194 } 2195 2196 s->base.is_jmp = DISAS_NORETURN; 2197 } 2198 2199 /* Jump to eip+diff, truncating the result to OT. */ 2200 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num) 2201 { 2202 bool use_goto_tb = s->jmp_opt; 2203 target_ulong mask = -1; 2204 target_ulong new_pc = s->pc + diff; 2205 target_ulong new_eip = new_pc - s->cs_base; 2206 2207 assert(!s->cc_op_dirty); 2208 2209 /* In 64-bit mode, operand size is fixed at 64 bits. */ 2210 if (!CODE64(s)) { 2211 if (ot == MO_16) { 2212 mask = 0xffff; 2213 if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) { 2214 use_goto_tb = false; 2215 } 2216 } else { 2217 mask = 0xffffffff; 2218 } 2219 } 2220 new_eip &= mask; 2221 2222 if (tb_cflags(s->base.tb) & CF_PCREL) { 2223 tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save); 2224 /* 2225 * If we can prove the branch does not leave the page and we have 2226 * no extra masking to apply (data16 branch in code32, see above), 2227 * then we have also proven that the addition does not wrap. 2228 */ 2229 if (!use_goto_tb || !translator_is_same_page(&s->base, new_pc)) { 2230 tcg_gen_andi_tl(cpu_eip, cpu_eip, mask); 2231 use_goto_tb = false; 2232 } 2233 } else if (!CODE64(s)) { 2234 new_pc = (uint32_t)(new_eip + s->cs_base); 2235 } 2236 2237 if (use_goto_tb && translator_use_goto_tb(&s->base, new_pc)) { 2238 /* jump to same page: we can use a direct jump */ 2239 tcg_gen_goto_tb(tb_num); 2240 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2241 tcg_gen_movi_tl(cpu_eip, new_eip); 2242 } 2243 tcg_gen_exit_tb(s->base.tb, tb_num); 2244 s->base.is_jmp = DISAS_NORETURN; 2245 } else { 2246 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2247 tcg_gen_movi_tl(cpu_eip, new_eip); 2248 } 2249 if (s->jmp_opt) { 2250 gen_eob(s, DISAS_JUMP); /* jump to another page */ 2251 } else { 2252 gen_eob(s, DISAS_EOB_ONLY); /* exit to main loop */ 2253 } 2254 } 2255 } 2256 2257 /* Jump to eip+diff, truncating to the current code size. */ 2258 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num) 2259 { 2260 /* CODE64 ignores the OT argument, so we need not consider it. */ 2261 gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num); 2262 } 2263 2264 static inline void gen_ldq_env_A0(DisasContext *s, int offset) 2265 { 2266 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2267 tcg_gen_st_i64(s->tmp1_i64, tcg_env, offset); 2268 } 2269 2270 static inline void gen_stq_env_A0(DisasContext *s, int offset) 2271 { 2272 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, offset); 2273 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2274 } 2275 2276 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align) 2277 { 2278 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2279 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2280 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2281 int mem_index = s->mem_index; 2282 TCGv_i128 t = tcg_temp_new_i128(); 2283 2284 tcg_gen_qemu_ld_i128(t, s->A0, mem_index, mop); 2285 tcg_gen_st_i128(t, tcg_env, offset); 2286 } 2287 2288 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align) 2289 { 2290 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2291 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2292 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2293 int mem_index = s->mem_index; 2294 TCGv_i128 t = tcg_temp_new_i128(); 2295 2296 tcg_gen_ld_i128(t, tcg_env, offset); 2297 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop); 2298 } 2299 2300 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align) 2301 { 2302 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2303 int mem_index = s->mem_index; 2304 TCGv_i128 t0 = tcg_temp_new_i128(); 2305 TCGv_i128 t1 = tcg_temp_new_i128(); 2306 2307 tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2308 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2309 tcg_gen_qemu_ld_i128(t1, s->tmp0, mem_index, mop); 2310 2311 tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2312 tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2313 } 2314 2315 static void gen_sty_env_A0(DisasContext *s, int offset, bool align) 2316 { 2317 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2318 int mem_index = s->mem_index; 2319 TCGv_i128 t = tcg_temp_new_i128(); 2320 2321 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2322 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2323 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2324 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2325 tcg_gen_qemu_st_i128(t, s->tmp0, mem_index, mop); 2326 } 2327 2328 #include "emit.c.inc" 2329 2330 static void gen_x87(DisasContext *s, X86DecodedInsn *decode) 2331 { 2332 bool update_fip = true; 2333 int b = decode->b; 2334 int modrm = s->modrm; 2335 int mod, rm, op; 2336 2337 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 2338 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 2339 /* XXX: what to do if illegal op ? */ 2340 gen_exception(s, EXCP07_PREX); 2341 return; 2342 } 2343 mod = (modrm >> 6) & 3; 2344 rm = modrm & 7; 2345 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 2346 if (mod != 3) { 2347 /* memory op */ 2348 TCGv ea = gen_lea_modrm_1(s, decode->mem, false); 2349 TCGv last_addr = tcg_temp_new(); 2350 bool update_fdp = true; 2351 2352 tcg_gen_mov_tl(last_addr, ea); 2353 gen_lea_v_seg(s, ea, decode->mem.def_seg, s->override); 2354 2355 switch (op) { 2356 case 0x00 ... 0x07: /* fxxxs */ 2357 case 0x10 ... 0x17: /* fixxxl */ 2358 case 0x20 ... 0x27: /* fxxxl */ 2359 case 0x30 ... 0x37: /* fixxx */ 2360 { 2361 int op1; 2362 op1 = op & 7; 2363 2364 switch (op >> 4) { 2365 case 0: 2366 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2367 s->mem_index, MO_LEUL); 2368 gen_helper_flds_FT0(tcg_env, s->tmp2_i32); 2369 break; 2370 case 1: 2371 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2372 s->mem_index, MO_LEUL); 2373 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2374 break; 2375 case 2: 2376 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2377 s->mem_index, MO_LEUQ); 2378 gen_helper_fldl_FT0(tcg_env, s->tmp1_i64); 2379 break; 2380 case 3: 2381 default: 2382 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2383 s->mem_index, MO_LESW); 2384 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2385 break; 2386 } 2387 2388 gen_helper_fp_arith_ST0_FT0(op1); 2389 if (op1 == 3) { 2390 /* fcomp needs pop */ 2391 gen_helper_fpop(tcg_env); 2392 } 2393 } 2394 break; 2395 case 0x08: /* flds */ 2396 case 0x0a: /* fsts */ 2397 case 0x0b: /* fstps */ 2398 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 2399 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 2400 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 2401 switch (op & 7) { 2402 case 0: 2403 switch (op >> 4) { 2404 case 0: 2405 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2406 s->mem_index, MO_LEUL); 2407 gen_helper_flds_ST0(tcg_env, s->tmp2_i32); 2408 break; 2409 case 1: 2410 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2411 s->mem_index, MO_LEUL); 2412 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2413 break; 2414 case 2: 2415 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2416 s->mem_index, MO_LEUQ); 2417 gen_helper_fldl_ST0(tcg_env, s->tmp1_i64); 2418 break; 2419 case 3: 2420 default: 2421 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2422 s->mem_index, MO_LESW); 2423 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2424 break; 2425 } 2426 break; 2427 case 1: 2428 /* XXX: the corresponding CPUID bit must be tested ! */ 2429 switch (op >> 4) { 2430 case 1: 2431 gen_helper_fisttl_ST0(s->tmp2_i32, tcg_env); 2432 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2433 s->mem_index, MO_LEUL); 2434 break; 2435 case 2: 2436 gen_helper_fisttll_ST0(s->tmp1_i64, tcg_env); 2437 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2438 s->mem_index, MO_LEUQ); 2439 break; 2440 case 3: 2441 default: 2442 gen_helper_fistt_ST0(s->tmp2_i32, tcg_env); 2443 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2444 s->mem_index, MO_LEUW); 2445 break; 2446 } 2447 gen_helper_fpop(tcg_env); 2448 break; 2449 default: 2450 switch (op >> 4) { 2451 case 0: 2452 gen_helper_fsts_ST0(s->tmp2_i32, tcg_env); 2453 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2454 s->mem_index, MO_LEUL); 2455 break; 2456 case 1: 2457 gen_helper_fistl_ST0(s->tmp2_i32, tcg_env); 2458 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2459 s->mem_index, MO_LEUL); 2460 break; 2461 case 2: 2462 gen_helper_fstl_ST0(s->tmp1_i64, tcg_env); 2463 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2464 s->mem_index, MO_LEUQ); 2465 break; 2466 case 3: 2467 default: 2468 gen_helper_fist_ST0(s->tmp2_i32, tcg_env); 2469 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2470 s->mem_index, MO_LEUW); 2471 break; 2472 } 2473 if ((op & 7) == 3) { 2474 gen_helper_fpop(tcg_env); 2475 } 2476 break; 2477 } 2478 break; 2479 case 0x0c: /* fldenv mem */ 2480 gen_helper_fldenv(tcg_env, s->A0, 2481 tcg_constant_i32(s->dflag - 1)); 2482 update_fip = update_fdp = false; 2483 break; 2484 case 0x0d: /* fldcw mem */ 2485 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2486 s->mem_index, MO_LEUW); 2487 gen_helper_fldcw(tcg_env, s->tmp2_i32); 2488 update_fip = update_fdp = false; 2489 break; 2490 case 0x0e: /* fnstenv mem */ 2491 gen_helper_fstenv(tcg_env, s->A0, 2492 tcg_constant_i32(s->dflag - 1)); 2493 update_fip = update_fdp = false; 2494 break; 2495 case 0x0f: /* fnstcw mem */ 2496 gen_helper_fnstcw(s->tmp2_i32, tcg_env); 2497 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2498 s->mem_index, MO_LEUW); 2499 update_fip = update_fdp = false; 2500 break; 2501 case 0x1d: /* fldt mem */ 2502 gen_helper_fldt_ST0(tcg_env, s->A0); 2503 break; 2504 case 0x1f: /* fstpt mem */ 2505 gen_helper_fstt_ST0(tcg_env, s->A0); 2506 gen_helper_fpop(tcg_env); 2507 break; 2508 case 0x2c: /* frstor mem */ 2509 gen_helper_frstor(tcg_env, s->A0, 2510 tcg_constant_i32(s->dflag - 1)); 2511 update_fip = update_fdp = false; 2512 break; 2513 case 0x2e: /* fnsave mem */ 2514 gen_helper_fsave(tcg_env, s->A0, 2515 tcg_constant_i32(s->dflag - 1)); 2516 update_fip = update_fdp = false; 2517 break; 2518 case 0x2f: /* fnstsw mem */ 2519 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2520 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2521 s->mem_index, MO_LEUW); 2522 update_fip = update_fdp = false; 2523 break; 2524 case 0x3c: /* fbld */ 2525 gen_helper_fbld_ST0(tcg_env, s->A0); 2526 break; 2527 case 0x3e: /* fbstp */ 2528 gen_helper_fbst_ST0(tcg_env, s->A0); 2529 gen_helper_fpop(tcg_env); 2530 break; 2531 case 0x3d: /* fildll */ 2532 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2533 s->mem_index, MO_LEUQ); 2534 gen_helper_fildll_ST0(tcg_env, s->tmp1_i64); 2535 break; 2536 case 0x3f: /* fistpll */ 2537 gen_helper_fistll_ST0(s->tmp1_i64, tcg_env); 2538 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2539 s->mem_index, MO_LEUQ); 2540 gen_helper_fpop(tcg_env); 2541 break; 2542 default: 2543 goto illegal_op; 2544 } 2545 2546 if (update_fdp) { 2547 int last_seg = s->override >= 0 ? s->override : decode->mem.def_seg; 2548 2549 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 2550 offsetof(CPUX86State, 2551 segs[last_seg].selector)); 2552 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 2553 offsetof(CPUX86State, fpds)); 2554 tcg_gen_st_tl(last_addr, tcg_env, 2555 offsetof(CPUX86State, fpdp)); 2556 } 2557 } else { 2558 /* register float ops */ 2559 int opreg = rm; 2560 2561 switch (op) { 2562 case 0x08: /* fld sti */ 2563 gen_helper_fpush(tcg_env); 2564 gen_helper_fmov_ST0_STN(tcg_env, 2565 tcg_constant_i32((opreg + 1) & 7)); 2566 break; 2567 case 0x09: /* fxchg sti */ 2568 case 0x29: /* fxchg4 sti, undocumented op */ 2569 case 0x39: /* fxchg7 sti, undocumented op */ 2570 gen_helper_fxchg_ST0_STN(tcg_env, tcg_constant_i32(opreg)); 2571 break; 2572 case 0x0a: /* grp d9/2 */ 2573 switch (rm) { 2574 case 0: /* fnop */ 2575 /* 2576 * check exceptions (FreeBSD FPU probe) 2577 * needs to be treated as I/O because of ferr_irq 2578 */ 2579 translator_io_start(&s->base); 2580 gen_helper_fwait(tcg_env); 2581 update_fip = false; 2582 break; 2583 default: 2584 goto illegal_op; 2585 } 2586 break; 2587 case 0x0c: /* grp d9/4 */ 2588 switch (rm) { 2589 case 0: /* fchs */ 2590 gen_helper_fchs_ST0(tcg_env); 2591 break; 2592 case 1: /* fabs */ 2593 gen_helper_fabs_ST0(tcg_env); 2594 break; 2595 case 4: /* ftst */ 2596 gen_helper_fldz_FT0(tcg_env); 2597 gen_helper_fcom_ST0_FT0(tcg_env); 2598 break; 2599 case 5: /* fxam */ 2600 gen_helper_fxam_ST0(tcg_env); 2601 break; 2602 default: 2603 goto illegal_op; 2604 } 2605 break; 2606 case 0x0d: /* grp d9/5 */ 2607 { 2608 switch (rm) { 2609 case 0: 2610 gen_helper_fpush(tcg_env); 2611 gen_helper_fld1_ST0(tcg_env); 2612 break; 2613 case 1: 2614 gen_helper_fpush(tcg_env); 2615 gen_helper_fldl2t_ST0(tcg_env); 2616 break; 2617 case 2: 2618 gen_helper_fpush(tcg_env); 2619 gen_helper_fldl2e_ST0(tcg_env); 2620 break; 2621 case 3: 2622 gen_helper_fpush(tcg_env); 2623 gen_helper_fldpi_ST0(tcg_env); 2624 break; 2625 case 4: 2626 gen_helper_fpush(tcg_env); 2627 gen_helper_fldlg2_ST0(tcg_env); 2628 break; 2629 case 5: 2630 gen_helper_fpush(tcg_env); 2631 gen_helper_fldln2_ST0(tcg_env); 2632 break; 2633 case 6: 2634 gen_helper_fpush(tcg_env); 2635 gen_helper_fldz_ST0(tcg_env); 2636 break; 2637 default: 2638 goto illegal_op; 2639 } 2640 } 2641 break; 2642 case 0x0e: /* grp d9/6 */ 2643 switch (rm) { 2644 case 0: /* f2xm1 */ 2645 gen_helper_f2xm1(tcg_env); 2646 break; 2647 case 1: /* fyl2x */ 2648 gen_helper_fyl2x(tcg_env); 2649 break; 2650 case 2: /* fptan */ 2651 gen_helper_fptan(tcg_env); 2652 break; 2653 case 3: /* fpatan */ 2654 gen_helper_fpatan(tcg_env); 2655 break; 2656 case 4: /* fxtract */ 2657 gen_helper_fxtract(tcg_env); 2658 break; 2659 case 5: /* fprem1 */ 2660 gen_helper_fprem1(tcg_env); 2661 break; 2662 case 6: /* fdecstp */ 2663 gen_helper_fdecstp(tcg_env); 2664 break; 2665 default: 2666 case 7: /* fincstp */ 2667 gen_helper_fincstp(tcg_env); 2668 break; 2669 } 2670 break; 2671 case 0x0f: /* grp d9/7 */ 2672 switch (rm) { 2673 case 0: /* fprem */ 2674 gen_helper_fprem(tcg_env); 2675 break; 2676 case 1: /* fyl2xp1 */ 2677 gen_helper_fyl2xp1(tcg_env); 2678 break; 2679 case 2: /* fsqrt */ 2680 gen_helper_fsqrt(tcg_env); 2681 break; 2682 case 3: /* fsincos */ 2683 gen_helper_fsincos(tcg_env); 2684 break; 2685 case 5: /* fscale */ 2686 gen_helper_fscale(tcg_env); 2687 break; 2688 case 4: /* frndint */ 2689 gen_helper_frndint(tcg_env); 2690 break; 2691 case 6: /* fsin */ 2692 gen_helper_fsin(tcg_env); 2693 break; 2694 default: 2695 case 7: /* fcos */ 2696 gen_helper_fcos(tcg_env); 2697 break; 2698 } 2699 break; 2700 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 2701 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 2702 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 2703 { 2704 int op1; 2705 2706 op1 = op & 7; 2707 if (op >= 0x20) { 2708 gen_helper_fp_arith_STN_ST0(op1, opreg); 2709 if (op >= 0x30) { 2710 gen_helper_fpop(tcg_env); 2711 } 2712 } else { 2713 gen_helper_fmov_FT0_STN(tcg_env, 2714 tcg_constant_i32(opreg)); 2715 gen_helper_fp_arith_ST0_FT0(op1); 2716 } 2717 } 2718 break; 2719 case 0x02: /* fcom */ 2720 case 0x22: /* fcom2, undocumented op */ 2721 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2722 gen_helper_fcom_ST0_FT0(tcg_env); 2723 break; 2724 case 0x03: /* fcomp */ 2725 case 0x23: /* fcomp3, undocumented op */ 2726 case 0x32: /* fcomp5, undocumented op */ 2727 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2728 gen_helper_fcom_ST0_FT0(tcg_env); 2729 gen_helper_fpop(tcg_env); 2730 break; 2731 case 0x15: /* da/5 */ 2732 switch (rm) { 2733 case 1: /* fucompp */ 2734 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2735 gen_helper_fucom_ST0_FT0(tcg_env); 2736 gen_helper_fpop(tcg_env); 2737 gen_helper_fpop(tcg_env); 2738 break; 2739 default: 2740 goto illegal_op; 2741 } 2742 break; 2743 case 0x1c: 2744 switch (rm) { 2745 case 0: /* feni (287 only, just do nop here) */ 2746 break; 2747 case 1: /* fdisi (287 only, just do nop here) */ 2748 break; 2749 case 2: /* fclex */ 2750 gen_helper_fclex(tcg_env); 2751 update_fip = false; 2752 break; 2753 case 3: /* fninit */ 2754 gen_helper_fninit(tcg_env); 2755 update_fip = false; 2756 break; 2757 case 4: /* fsetpm (287 only, just do nop here) */ 2758 break; 2759 default: 2760 goto illegal_op; 2761 } 2762 break; 2763 case 0x1d: /* fucomi */ 2764 if (!(s->cpuid_features & CPUID_CMOV)) { 2765 goto illegal_op; 2766 } 2767 gen_update_cc_op(s); 2768 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2769 gen_helper_fucomi_ST0_FT0(tcg_env); 2770 assume_cc_op(s, CC_OP_EFLAGS); 2771 break; 2772 case 0x1e: /* fcomi */ 2773 if (!(s->cpuid_features & CPUID_CMOV)) { 2774 goto illegal_op; 2775 } 2776 gen_update_cc_op(s); 2777 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2778 gen_helper_fcomi_ST0_FT0(tcg_env); 2779 assume_cc_op(s, CC_OP_EFLAGS); 2780 break; 2781 case 0x28: /* ffree sti */ 2782 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2783 break; 2784 case 0x2a: /* fst sti */ 2785 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2786 break; 2787 case 0x2b: /* fstp sti */ 2788 case 0x0b: /* fstp1 sti, undocumented op */ 2789 case 0x3a: /* fstp8 sti, undocumented op */ 2790 case 0x3b: /* fstp9 sti, undocumented op */ 2791 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2792 gen_helper_fpop(tcg_env); 2793 break; 2794 case 0x2c: /* fucom st(i) */ 2795 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2796 gen_helper_fucom_ST0_FT0(tcg_env); 2797 break; 2798 case 0x2d: /* fucomp st(i) */ 2799 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2800 gen_helper_fucom_ST0_FT0(tcg_env); 2801 gen_helper_fpop(tcg_env); 2802 break; 2803 case 0x33: /* de/3 */ 2804 switch (rm) { 2805 case 1: /* fcompp */ 2806 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2807 gen_helper_fcom_ST0_FT0(tcg_env); 2808 gen_helper_fpop(tcg_env); 2809 gen_helper_fpop(tcg_env); 2810 break; 2811 default: 2812 goto illegal_op; 2813 } 2814 break; 2815 case 0x38: /* ffreep sti, undocumented op */ 2816 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2817 gen_helper_fpop(tcg_env); 2818 break; 2819 case 0x3c: /* df/4 */ 2820 switch (rm) { 2821 case 0: 2822 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2823 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 2824 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 2825 break; 2826 default: 2827 goto illegal_op; 2828 } 2829 break; 2830 case 0x3d: /* fucomip */ 2831 if (!(s->cpuid_features & CPUID_CMOV)) { 2832 goto illegal_op; 2833 } 2834 gen_update_cc_op(s); 2835 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2836 gen_helper_fucomi_ST0_FT0(tcg_env); 2837 gen_helper_fpop(tcg_env); 2838 assume_cc_op(s, CC_OP_EFLAGS); 2839 break; 2840 case 0x3e: /* fcomip */ 2841 if (!(s->cpuid_features & CPUID_CMOV)) { 2842 goto illegal_op; 2843 } 2844 gen_update_cc_op(s); 2845 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2846 gen_helper_fcomi_ST0_FT0(tcg_env); 2847 gen_helper_fpop(tcg_env); 2848 assume_cc_op(s, CC_OP_EFLAGS); 2849 break; 2850 case 0x10 ... 0x13: /* fcmovxx */ 2851 case 0x18 ... 0x1b: 2852 { 2853 int op1; 2854 TCGLabel *l1; 2855 static const uint8_t fcmov_cc[8] = { 2856 (JCC_B << 1), 2857 (JCC_Z << 1), 2858 (JCC_BE << 1), 2859 (JCC_P << 1), 2860 }; 2861 2862 if (!(s->cpuid_features & CPUID_CMOV)) { 2863 goto illegal_op; 2864 } 2865 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 2866 l1 = gen_new_label(); 2867 gen_jcc1_noeob(s, op1, l1); 2868 gen_helper_fmov_ST0_STN(tcg_env, 2869 tcg_constant_i32(opreg)); 2870 gen_set_label(l1); 2871 } 2872 break; 2873 default: 2874 goto illegal_op; 2875 } 2876 } 2877 2878 if (update_fip) { 2879 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 2880 offsetof(CPUX86State, segs[R_CS].selector)); 2881 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 2882 offsetof(CPUX86State, fpcs)); 2883 tcg_gen_st_tl(eip_cur_tl(s), 2884 tcg_env, offsetof(CPUX86State, fpip)); 2885 } 2886 return; 2887 2888 illegal_op: 2889 gen_illegal_opcode(s); 2890 } 2891 2892 static void gen_multi0F(DisasContext *s, X86DecodedInsn *decode) 2893 { 2894 int prefixes = s->prefix; 2895 MemOp dflag = s->dflag; 2896 int b = decode->b + 0x100; 2897 int modrm = s->modrm; 2898 MemOp ot; 2899 int reg, rm, mod, op; 2900 2901 /* now check op code */ 2902 switch (b) { 2903 case 0x1c7: /* RDSEED, RDPID with f3 prefix */ 2904 mod = (modrm >> 6) & 3; 2905 switch ((modrm >> 3) & 7) { 2906 case 7: 2907 if (mod != 3 || 2908 (s->prefix & PREFIX_REPNZ)) { 2909 goto illegal_op; 2910 } 2911 if (s->prefix & PREFIX_REPZ) { 2912 if (!(s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_RDPID)) { 2913 goto illegal_op; 2914 } 2915 gen_helper_rdpid(s->T0, tcg_env); 2916 rm = (modrm & 7) | REX_B(s); 2917 gen_op_mov_reg_v(s, dflag, rm, s->T0); 2918 break; 2919 } else { 2920 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) { 2921 goto illegal_op; 2922 } 2923 goto do_rdrand; 2924 } 2925 2926 case 6: /* RDRAND */ 2927 if (mod != 3 || 2928 (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) || 2929 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { 2930 goto illegal_op; 2931 } 2932 do_rdrand: 2933 translator_io_start(&s->base); 2934 gen_helper_rdrand(s->T0, tcg_env); 2935 rm = (modrm & 7) | REX_B(s); 2936 gen_op_mov_reg_v(s, dflag, rm, s->T0); 2937 assume_cc_op(s, CC_OP_EFLAGS); 2938 break; 2939 2940 default: 2941 goto illegal_op; 2942 } 2943 break; 2944 2945 case 0x100: 2946 mod = (modrm >> 6) & 3; 2947 op = (modrm >> 3) & 7; 2948 switch(op) { 2949 case 0: /* sldt */ 2950 if (!PE(s) || VM86(s)) 2951 goto illegal_op; 2952 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 2953 break; 2954 } 2955 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ); 2956 tcg_gen_ld32u_tl(s->T0, tcg_env, 2957 offsetof(CPUX86State, ldt.selector)); 2958 ot = mod == 3 ? dflag : MO_16; 2959 gen_st_modrm(s, decode, ot); 2960 break; 2961 case 2: /* lldt */ 2962 if (!PE(s) || VM86(s)) 2963 goto illegal_op; 2964 if (check_cpl0(s)) { 2965 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE); 2966 gen_ld_modrm(s, decode, MO_16); 2967 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 2968 gen_helper_lldt(tcg_env, s->tmp2_i32); 2969 } 2970 break; 2971 case 1: /* str */ 2972 if (!PE(s) || VM86(s)) 2973 goto illegal_op; 2974 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 2975 break; 2976 } 2977 gen_svm_check_intercept(s, SVM_EXIT_TR_READ); 2978 tcg_gen_ld32u_tl(s->T0, tcg_env, 2979 offsetof(CPUX86State, tr.selector)); 2980 ot = mod == 3 ? dflag : MO_16; 2981 gen_st_modrm(s, decode, ot); 2982 break; 2983 case 3: /* ltr */ 2984 if (!PE(s) || VM86(s)) 2985 goto illegal_op; 2986 if (check_cpl0(s)) { 2987 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE); 2988 gen_ld_modrm(s, decode, MO_16); 2989 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 2990 gen_helper_ltr(tcg_env, s->tmp2_i32); 2991 } 2992 break; 2993 case 4: /* verr */ 2994 case 5: /* verw */ 2995 if (!PE(s) || VM86(s)) 2996 goto illegal_op; 2997 gen_ld_modrm(s, decode, MO_16); 2998 gen_update_cc_op(s); 2999 if (op == 4) { 3000 gen_helper_verr(tcg_env, s->T0); 3001 } else { 3002 gen_helper_verw(tcg_env, s->T0); 3003 } 3004 assume_cc_op(s, CC_OP_EFLAGS); 3005 break; 3006 default: 3007 goto illegal_op; 3008 } 3009 break; 3010 3011 case 0x101: 3012 switch (modrm) { 3013 CASE_MODRM_MEM_OP(0): /* sgdt */ 3014 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3015 break; 3016 } 3017 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ); 3018 gen_lea_modrm(s, decode); 3019 tcg_gen_ld32u_tl(s->T0, 3020 tcg_env, offsetof(CPUX86State, gdt.limit)); 3021 gen_op_st_v(s, MO_16, s->T0, s->A0); 3022 gen_add_A0_im(s, 2); 3023 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3024 /* 3025 * NB: Despite a confusing description in Intel CPU documentation, 3026 * all 32-bits are written regardless of operand size. 3027 */ 3028 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3029 break; 3030 3031 case 0xc8: /* monitor */ 3032 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3033 goto illegal_op; 3034 } 3035 gen_update_cc_op(s); 3036 gen_update_eip_cur(s); 3037 gen_lea_v_seg(s, cpu_regs[R_EAX], R_DS, s->override); 3038 gen_helper_monitor(tcg_env, s->A0); 3039 break; 3040 3041 case 0xc9: /* mwait */ 3042 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3043 goto illegal_op; 3044 } 3045 gen_update_cc_op(s); 3046 gen_update_eip_cur(s); 3047 gen_helper_mwait(tcg_env, cur_insn_len_i32(s)); 3048 s->base.is_jmp = DISAS_NORETURN; 3049 break; 3050 3051 case 0xca: /* clac */ 3052 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3053 || CPL(s) != 0) { 3054 goto illegal_op; 3055 } 3056 gen_reset_eflags(s, AC_MASK); 3057 s->base.is_jmp = DISAS_EOB_NEXT; 3058 break; 3059 3060 case 0xcb: /* stac */ 3061 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3062 || CPL(s) != 0) { 3063 goto illegal_op; 3064 } 3065 gen_set_eflags(s, AC_MASK); 3066 s->base.is_jmp = DISAS_EOB_NEXT; 3067 break; 3068 3069 CASE_MODRM_MEM_OP(1): /* sidt */ 3070 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3071 break; 3072 } 3073 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ); 3074 gen_lea_modrm(s, decode); 3075 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.limit)); 3076 gen_op_st_v(s, MO_16, s->T0, s->A0); 3077 gen_add_A0_im(s, 2); 3078 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3079 /* 3080 * NB: Despite a confusing description in Intel CPU documentation, 3081 * all 32-bits are written regardless of operand size. 3082 */ 3083 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3084 break; 3085 3086 case 0xd0: /* xgetbv */ 3087 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3088 || (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { 3089 goto illegal_op; 3090 } 3091 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3092 gen_helper_xgetbv(s->tmp1_i64, tcg_env, s->tmp2_i32); 3093 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3094 break; 3095 3096 case 0xd1: /* xsetbv */ 3097 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3098 || (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { 3099 goto illegal_op; 3100 } 3101 gen_svm_check_intercept(s, SVM_EXIT_XSETBV); 3102 if (!check_cpl0(s)) { 3103 break; 3104 } 3105 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3106 cpu_regs[R_EDX]); 3107 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3108 gen_helper_xsetbv(tcg_env, s->tmp2_i32, s->tmp1_i64); 3109 /* End TB because translation flags may change. */ 3110 s->base.is_jmp = DISAS_EOB_NEXT; 3111 break; 3112 3113 case 0xd8: /* VMRUN */ 3114 if (!SVME(s) || !PE(s)) { 3115 goto illegal_op; 3116 } 3117 if (!check_cpl0(s)) { 3118 break; 3119 } 3120 gen_update_cc_op(s); 3121 gen_update_eip_cur(s); 3122 /* 3123 * Reloads INHIBIT_IRQ mask as well as TF and RF with guest state. 3124 * The usual gen_eob() handling is performed on vmexit after 3125 * host state is reloaded. 3126 */ 3127 gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1), 3128 cur_insn_len_i32(s)); 3129 tcg_gen_exit_tb(NULL, 0); 3130 s->base.is_jmp = DISAS_NORETURN; 3131 break; 3132 3133 case 0xd9: /* VMMCALL */ 3134 if (!SVME(s)) { 3135 goto illegal_op; 3136 } 3137 gen_update_cc_op(s); 3138 gen_update_eip_cur(s); 3139 gen_helper_vmmcall(tcg_env); 3140 break; 3141 3142 case 0xda: /* VMLOAD */ 3143 if (!SVME(s) || !PE(s)) { 3144 goto illegal_op; 3145 } 3146 if (!check_cpl0(s)) { 3147 break; 3148 } 3149 gen_update_cc_op(s); 3150 gen_update_eip_cur(s); 3151 gen_helper_vmload(tcg_env, tcg_constant_i32(s->aflag - 1)); 3152 break; 3153 3154 case 0xdb: /* VMSAVE */ 3155 if (!SVME(s) || !PE(s)) { 3156 goto illegal_op; 3157 } 3158 if (!check_cpl0(s)) { 3159 break; 3160 } 3161 gen_update_cc_op(s); 3162 gen_update_eip_cur(s); 3163 gen_helper_vmsave(tcg_env, tcg_constant_i32(s->aflag - 1)); 3164 break; 3165 3166 case 0xdc: /* STGI */ 3167 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3168 || !PE(s)) { 3169 goto illegal_op; 3170 } 3171 if (!check_cpl0(s)) { 3172 break; 3173 } 3174 gen_update_cc_op(s); 3175 gen_helper_stgi(tcg_env); 3176 s->base.is_jmp = DISAS_EOB_NEXT; 3177 break; 3178 3179 case 0xdd: /* CLGI */ 3180 if (!SVME(s) || !PE(s)) { 3181 goto illegal_op; 3182 } 3183 if (!check_cpl0(s)) { 3184 break; 3185 } 3186 gen_update_cc_op(s); 3187 gen_update_eip_cur(s); 3188 gen_helper_clgi(tcg_env); 3189 break; 3190 3191 case 0xde: /* SKINIT */ 3192 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3193 || !PE(s)) { 3194 goto illegal_op; 3195 } 3196 gen_svm_check_intercept(s, SVM_EXIT_SKINIT); 3197 /* If not intercepted, not implemented -- raise #UD. */ 3198 goto illegal_op; 3199 3200 case 0xdf: /* INVLPGA */ 3201 if (!SVME(s) || !PE(s)) { 3202 goto illegal_op; 3203 } 3204 if (!check_cpl0(s)) { 3205 break; 3206 } 3207 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA); 3208 if (s->aflag == MO_64) { 3209 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 3210 } else { 3211 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]); 3212 } 3213 gen_helper_flush_page(tcg_env, s->A0); 3214 s->base.is_jmp = DISAS_EOB_NEXT; 3215 break; 3216 3217 CASE_MODRM_MEM_OP(2): /* lgdt */ 3218 if (!check_cpl0(s)) { 3219 break; 3220 } 3221 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE); 3222 gen_lea_modrm(s, decode); 3223 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3224 gen_add_A0_im(s, 2); 3225 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3226 if (dflag == MO_16) { 3227 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3228 } 3229 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3230 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, gdt.limit)); 3231 break; 3232 3233 CASE_MODRM_MEM_OP(3): /* lidt */ 3234 if (!check_cpl0(s)) { 3235 break; 3236 } 3237 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE); 3238 gen_lea_modrm(s, decode); 3239 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3240 gen_add_A0_im(s, 2); 3241 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3242 if (dflag == MO_16) { 3243 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3244 } 3245 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3246 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, idt.limit)); 3247 break; 3248 3249 CASE_MODRM_OP(4): /* smsw */ 3250 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3251 break; 3252 } 3253 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0); 3254 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, cr[0])); 3255 /* 3256 * In 32-bit mode, the higher 16 bits of the destination 3257 * register are undefined. In practice CR0[31:0] is stored 3258 * just like in 64-bit mode. 3259 */ 3260 mod = (modrm >> 6) & 3; 3261 ot = (mod != 3 ? MO_16 : s->dflag); 3262 gen_st_modrm(s, decode, ot); 3263 break; 3264 case 0xee: /* rdpkru */ 3265 if (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ)) { 3266 goto illegal_op; 3267 } 3268 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3269 gen_helper_rdpkru(s->tmp1_i64, tcg_env, s->tmp2_i32); 3270 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3271 break; 3272 case 0xef: /* wrpkru */ 3273 if (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ)) { 3274 goto illegal_op; 3275 } 3276 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3277 cpu_regs[R_EDX]); 3278 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3279 gen_helper_wrpkru(tcg_env, s->tmp2_i32, s->tmp1_i64); 3280 break; 3281 3282 CASE_MODRM_OP(6): /* lmsw */ 3283 if (!check_cpl0(s)) { 3284 break; 3285 } 3286 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 3287 gen_ld_modrm(s, decode, MO_16); 3288 /* 3289 * Only the 4 lower bits of CR0 are modified. 3290 * PE cannot be set to zero if already set to one. 3291 */ 3292 tcg_gen_ld_tl(s->T1, tcg_env, offsetof(CPUX86State, cr[0])); 3293 tcg_gen_andi_tl(s->T0, s->T0, 0xf); 3294 tcg_gen_andi_tl(s->T1, s->T1, ~0xe); 3295 tcg_gen_or_tl(s->T0, s->T0, s->T1); 3296 gen_helper_write_crN(tcg_env, tcg_constant_i32(0), s->T0); 3297 s->base.is_jmp = DISAS_EOB_NEXT; 3298 break; 3299 3300 CASE_MODRM_MEM_OP(7): /* invlpg */ 3301 if (!check_cpl0(s)) { 3302 break; 3303 } 3304 gen_svm_check_intercept(s, SVM_EXIT_INVLPG); 3305 gen_lea_modrm(s, decode); 3306 gen_helper_flush_page(tcg_env, s->A0); 3307 s->base.is_jmp = DISAS_EOB_NEXT; 3308 break; 3309 3310 case 0xf8: /* swapgs */ 3311 #ifdef TARGET_X86_64 3312 if (CODE64(s)) { 3313 if (check_cpl0(s)) { 3314 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]); 3315 tcg_gen_ld_tl(cpu_seg_base[R_GS], tcg_env, 3316 offsetof(CPUX86State, kernelgsbase)); 3317 tcg_gen_st_tl(s->T0, tcg_env, 3318 offsetof(CPUX86State, kernelgsbase)); 3319 } 3320 break; 3321 } 3322 #endif 3323 goto illegal_op; 3324 3325 case 0xf9: /* rdtscp */ 3326 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) { 3327 goto illegal_op; 3328 } 3329 gen_update_cc_op(s); 3330 gen_update_eip_cur(s); 3331 translator_io_start(&s->base); 3332 gen_helper_rdtsc(tcg_env); 3333 gen_helper_rdpid(s->T0, tcg_env); 3334 gen_op_mov_reg_v(s, dflag, R_ECX, s->T0); 3335 break; 3336 3337 default: 3338 goto illegal_op; 3339 } 3340 break; 3341 3342 case 0x11a: 3343 if (s->flags & HF_MPX_EN_MASK) { 3344 mod = (modrm >> 6) & 3; 3345 reg = ((modrm >> 3) & 7) | REX_R(s); 3346 if (prefixes & PREFIX_REPZ) { 3347 /* bndcl */ 3348 if (reg >= 4 3349 || s->aflag == MO_16) { 3350 goto illegal_op; 3351 } 3352 gen_bndck(s, decode, TCG_COND_LTU, cpu_bndl[reg]); 3353 } else if (prefixes & PREFIX_REPNZ) { 3354 /* bndcu */ 3355 if (reg >= 4 3356 || s->aflag == MO_16) { 3357 goto illegal_op; 3358 } 3359 TCGv_i64 notu = tcg_temp_new_i64(); 3360 tcg_gen_not_i64(notu, cpu_bndu[reg]); 3361 gen_bndck(s, decode, TCG_COND_GTU, notu); 3362 } else if (prefixes & PREFIX_DATA) { 3363 /* bndmov -- from reg/mem */ 3364 if (reg >= 4 || s->aflag == MO_16) { 3365 goto illegal_op; 3366 } 3367 if (mod == 3) { 3368 int reg2 = (modrm & 7) | REX_B(s); 3369 if (reg2 >= 4) { 3370 goto illegal_op; 3371 } 3372 if (s->flags & HF_MPX_IU_MASK) { 3373 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]); 3374 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]); 3375 } 3376 } else { 3377 gen_lea_modrm(s, decode); 3378 if (CODE64(s)) { 3379 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 3380 s->mem_index, MO_LEUQ); 3381 tcg_gen_addi_tl(s->A0, s->A0, 8); 3382 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 3383 s->mem_index, MO_LEUQ); 3384 } else { 3385 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 3386 s->mem_index, MO_LEUL); 3387 tcg_gen_addi_tl(s->A0, s->A0, 4); 3388 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 3389 s->mem_index, MO_LEUL); 3390 } 3391 /* bnd registers are now in-use */ 3392 gen_set_hflag(s, HF_MPX_IU_MASK); 3393 } 3394 } else if (mod != 3) { 3395 /* bndldx */ 3396 AddressParts a = decode->mem; 3397 if (reg >= 4 3398 || s->aflag == MO_16 3399 || a.base < -1) { 3400 goto illegal_op; 3401 } 3402 if (a.base >= 0) { 3403 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 3404 } else { 3405 tcg_gen_movi_tl(s->A0, 0); 3406 } 3407 gen_lea_v_seg(s, s->A0, a.def_seg, s->override); 3408 if (a.index >= 0) { 3409 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 3410 } else { 3411 tcg_gen_movi_tl(s->T0, 0); 3412 } 3413 if (CODE64(s)) { 3414 gen_helper_bndldx64(cpu_bndl[reg], tcg_env, s->A0, s->T0); 3415 tcg_gen_ld_i64(cpu_bndu[reg], tcg_env, 3416 offsetof(CPUX86State, mmx_t0.MMX_Q(0))); 3417 } else { 3418 gen_helper_bndldx32(cpu_bndu[reg], tcg_env, s->A0, s->T0); 3419 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]); 3420 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32); 3421 } 3422 gen_set_hflag(s, HF_MPX_IU_MASK); 3423 } 3424 } 3425 break; 3426 case 0x11b: 3427 if (s->flags & HF_MPX_EN_MASK) { 3428 mod = (modrm >> 6) & 3; 3429 reg = ((modrm >> 3) & 7) | REX_R(s); 3430 if (mod != 3 && (prefixes & PREFIX_REPZ)) { 3431 /* bndmk */ 3432 if (reg >= 4 3433 || s->aflag == MO_16) { 3434 goto illegal_op; 3435 } 3436 AddressParts a = decode->mem; 3437 if (a.base >= 0) { 3438 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]); 3439 if (!CODE64(s)) { 3440 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]); 3441 } 3442 } else if (a.base == -1) { 3443 /* no base register has lower bound of 0 */ 3444 tcg_gen_movi_i64(cpu_bndl[reg], 0); 3445 } else { 3446 /* rip-relative generates #ud */ 3447 goto illegal_op; 3448 } 3449 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, decode->mem, false)); 3450 if (!CODE64(s)) { 3451 tcg_gen_ext32u_tl(s->A0, s->A0); 3452 } 3453 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0); 3454 /* bnd registers are now in-use */ 3455 gen_set_hflag(s, HF_MPX_IU_MASK); 3456 break; 3457 } else if (prefixes & PREFIX_REPNZ) { 3458 /* bndcn */ 3459 if (reg >= 4 3460 || s->aflag == MO_16) { 3461 goto illegal_op; 3462 } 3463 gen_bndck(s, decode, TCG_COND_GTU, cpu_bndu[reg]); 3464 } else if (prefixes & PREFIX_DATA) { 3465 /* bndmov -- to reg/mem */ 3466 if (reg >= 4 || s->aflag == MO_16) { 3467 goto illegal_op; 3468 } 3469 if (mod == 3) { 3470 int reg2 = (modrm & 7) | REX_B(s); 3471 if (reg2 >= 4) { 3472 goto illegal_op; 3473 } 3474 if (s->flags & HF_MPX_IU_MASK) { 3475 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]); 3476 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]); 3477 } 3478 } else { 3479 gen_lea_modrm(s, decode); 3480 if (CODE64(s)) { 3481 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 3482 s->mem_index, MO_LEUQ); 3483 tcg_gen_addi_tl(s->A0, s->A0, 8); 3484 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 3485 s->mem_index, MO_LEUQ); 3486 } else { 3487 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 3488 s->mem_index, MO_LEUL); 3489 tcg_gen_addi_tl(s->A0, s->A0, 4); 3490 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 3491 s->mem_index, MO_LEUL); 3492 } 3493 } 3494 } else if (mod != 3) { 3495 /* bndstx */ 3496 AddressParts a = decode->mem; 3497 if (reg >= 4 3498 || s->aflag == MO_16 3499 || a.base < -1) { 3500 goto illegal_op; 3501 } 3502 if (a.base >= 0) { 3503 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 3504 } else { 3505 tcg_gen_movi_tl(s->A0, 0); 3506 } 3507 gen_lea_v_seg(s, s->A0, a.def_seg, s->override); 3508 if (a.index >= 0) { 3509 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 3510 } else { 3511 tcg_gen_movi_tl(s->T0, 0); 3512 } 3513 if (CODE64(s)) { 3514 gen_helper_bndstx64(tcg_env, s->A0, s->T0, 3515 cpu_bndl[reg], cpu_bndu[reg]); 3516 } else { 3517 gen_helper_bndstx32(tcg_env, s->A0, s->T0, 3518 cpu_bndl[reg], cpu_bndu[reg]); 3519 } 3520 } 3521 } 3522 break; 3523 default: 3524 g_assert_not_reached(); 3525 } 3526 return; 3527 illegal_op: 3528 gen_illegal_opcode(s); 3529 return; 3530 } 3531 3532 #include "decode-new.c.inc" 3533 3534 void tcg_x86_init(void) 3535 { 3536 static const char reg_names[CPU_NB_REGS][4] = { 3537 #ifdef TARGET_X86_64 3538 [R_EAX] = "rax", 3539 [R_EBX] = "rbx", 3540 [R_ECX] = "rcx", 3541 [R_EDX] = "rdx", 3542 [R_ESI] = "rsi", 3543 [R_EDI] = "rdi", 3544 [R_EBP] = "rbp", 3545 [R_ESP] = "rsp", 3546 [8] = "r8", 3547 [9] = "r9", 3548 [10] = "r10", 3549 [11] = "r11", 3550 [12] = "r12", 3551 [13] = "r13", 3552 [14] = "r14", 3553 [15] = "r15", 3554 #else 3555 [R_EAX] = "eax", 3556 [R_EBX] = "ebx", 3557 [R_ECX] = "ecx", 3558 [R_EDX] = "edx", 3559 [R_ESI] = "esi", 3560 [R_EDI] = "edi", 3561 [R_EBP] = "ebp", 3562 [R_ESP] = "esp", 3563 #endif 3564 }; 3565 static const char eip_name[] = { 3566 #ifdef TARGET_X86_64 3567 "rip" 3568 #else 3569 "eip" 3570 #endif 3571 }; 3572 static const char seg_base_names[6][8] = { 3573 [R_CS] = "cs_base", 3574 [R_DS] = "ds_base", 3575 [R_ES] = "es_base", 3576 [R_FS] = "fs_base", 3577 [R_GS] = "gs_base", 3578 [R_SS] = "ss_base", 3579 }; 3580 static const char bnd_regl_names[4][8] = { 3581 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb" 3582 }; 3583 static const char bnd_regu_names[4][8] = { 3584 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" 3585 }; 3586 int i; 3587 3588 cpu_cc_op = tcg_global_mem_new_i32(tcg_env, 3589 offsetof(CPUX86State, cc_op), "cc_op"); 3590 cpu_cc_dst = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_dst), 3591 "cc_dst"); 3592 cpu_cc_src = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src), 3593 "cc_src"); 3594 cpu_cc_src2 = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src2), 3595 "cc_src2"); 3596 cpu_eip = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, eip), eip_name); 3597 3598 for (i = 0; i < CPU_NB_REGS; ++i) { 3599 cpu_regs[i] = tcg_global_mem_new(tcg_env, 3600 offsetof(CPUX86State, regs[i]), 3601 reg_names[i]); 3602 } 3603 3604 for (i = 0; i < 6; ++i) { 3605 cpu_seg_base[i] 3606 = tcg_global_mem_new(tcg_env, 3607 offsetof(CPUX86State, segs[i].base), 3608 seg_base_names[i]); 3609 } 3610 3611 for (i = 0; i < 4; ++i) { 3612 cpu_bndl[i] 3613 = tcg_global_mem_new_i64(tcg_env, 3614 offsetof(CPUX86State, bnd_regs[i].lb), 3615 bnd_regl_names[i]); 3616 cpu_bndu[i] 3617 = tcg_global_mem_new_i64(tcg_env, 3618 offsetof(CPUX86State, bnd_regs[i].ub), 3619 bnd_regu_names[i]); 3620 } 3621 } 3622 3623 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 3624 { 3625 DisasContext *dc = container_of(dcbase, DisasContext, base); 3626 CPUX86State *env = cpu_env(cpu); 3627 uint32_t flags = dc->base.tb->flags; 3628 uint32_t cflags = tb_cflags(dc->base.tb); 3629 int cpl = (flags >> HF_CPL_SHIFT) & 3; 3630 int iopl = (flags >> IOPL_SHIFT) & 3; 3631 3632 dc->cs_base = dc->base.tb->cs_base; 3633 dc->pc_save = dc->base.pc_next; 3634 dc->flags = flags; 3635 #ifndef CONFIG_USER_ONLY 3636 dc->cpl = cpl; 3637 dc->iopl = iopl; 3638 #endif 3639 3640 /* We make some simplifying assumptions; validate they're correct. */ 3641 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); 3642 g_assert(CPL(dc) == cpl); 3643 g_assert(IOPL(dc) == iopl); 3644 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0)); 3645 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0)); 3646 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0)); 3647 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0)); 3648 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0)); 3649 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0)); 3650 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0)); 3651 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0)); 3652 3653 dc->cc_op = CC_OP_DYNAMIC; 3654 dc->cc_op_dirty = false; 3655 /* select memory access functions */ 3656 dc->mem_index = cpu_mmu_index(cpu, false); 3657 dc->cpuid_features = env->features[FEAT_1_EDX]; 3658 dc->cpuid_ext_features = env->features[FEAT_1_ECX]; 3659 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; 3660 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; 3661 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; 3662 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX]; 3663 dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX]; 3664 dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; 3665 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || 3666 (flags & (HF_RF_MASK | HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 3667 /* 3668 * If jmp_opt, we want to handle each string instruction individually. 3669 * For icount also disable repz optimization so that each iteration 3670 * is accounted separately. 3671 * 3672 * FIXME: this is messy; it makes REP string instructions a lot less 3673 * efficient than they should be and it gets in the way of correct 3674 * handling of RF (interrupts or traps arriving after any iteration 3675 * of a repeated string instruction but the last should set RF to 1). 3676 * Perhaps it would be more efficient if REP string instructions were 3677 * always at the beginning of the TB, or even their own TB? That 3678 * would even allow accounting up to 64k iterations at once for icount. 3679 */ 3680 dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT); 3681 3682 dc->T0 = tcg_temp_new(); 3683 dc->T1 = tcg_temp_new(); 3684 dc->A0 = tcg_temp_new(); 3685 3686 dc->tmp0 = tcg_temp_new(); 3687 dc->tmp1_i64 = tcg_temp_new_i64(); 3688 dc->tmp2_i32 = tcg_temp_new_i32(); 3689 dc->tmp3_i32 = tcg_temp_new_i32(); 3690 dc->tmp4 = tcg_temp_new(); 3691 dc->cc_srcT = tcg_temp_new(); 3692 } 3693 3694 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) 3695 { 3696 } 3697 3698 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 3699 { 3700 DisasContext *dc = container_of(dcbase, DisasContext, base); 3701 target_ulong pc_arg = dc->base.pc_next; 3702 3703 dc->prev_insn_start = dc->base.insn_start; 3704 dc->prev_insn_end = tcg_last_op(); 3705 if (tb_cflags(dcbase->tb) & CF_PCREL) { 3706 pc_arg &= ~TARGET_PAGE_MASK; 3707 } 3708 tcg_gen_insn_start(pc_arg, dc->cc_op); 3709 } 3710 3711 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 3712 { 3713 DisasContext *dc = container_of(dcbase, DisasContext, base); 3714 bool orig_cc_op_dirty = dc->cc_op_dirty; 3715 CCOp orig_cc_op = dc->cc_op; 3716 target_ulong orig_pc_save = dc->pc_save; 3717 3718 #ifdef TARGET_VSYSCALL_PAGE 3719 /* 3720 * Detect entry into the vsyscall page and invoke the syscall. 3721 */ 3722 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) { 3723 gen_exception(dc, EXCP_VSYSCALL); 3724 dc->base.pc_next = dc->pc + 1; 3725 return; 3726 } 3727 #endif 3728 3729 switch (sigsetjmp(dc->jmpbuf, 0)) { 3730 case 0: 3731 disas_insn(dc, cpu); 3732 break; 3733 case 1: 3734 gen_exception_gpf(dc); 3735 break; 3736 case 2: 3737 /* Restore state that may affect the next instruction. */ 3738 dc->pc = dc->base.pc_next; 3739 assert(dc->cc_op_dirty == orig_cc_op_dirty); 3740 assert(dc->cc_op == orig_cc_op); 3741 assert(dc->pc_save == orig_pc_save); 3742 dc->base.num_insns--; 3743 tcg_remove_ops_after(dc->prev_insn_end); 3744 dc->base.insn_start = dc->prev_insn_start; 3745 dc->base.is_jmp = DISAS_TOO_MANY; 3746 return; 3747 default: 3748 g_assert_not_reached(); 3749 } 3750 3751 /* 3752 * Instruction decoding completed (possibly with #GP if the 3753 * 15-byte boundary was exceeded). 3754 */ 3755 dc->base.pc_next = dc->pc; 3756 if (dc->base.is_jmp == DISAS_NEXT) { 3757 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) { 3758 /* 3759 * If single step mode, we generate only one instruction and 3760 * generate an exception. 3761 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 3762 * the flag and abort the translation to give the irqs a 3763 * chance to happen. 3764 */ 3765 dc->base.is_jmp = DISAS_EOB_NEXT; 3766 } else if (!translator_is_same_page(&dc->base, dc->base.pc_next)) { 3767 dc->base.is_jmp = DISAS_TOO_MANY; 3768 } 3769 } 3770 } 3771 3772 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 3773 { 3774 DisasContext *dc = container_of(dcbase, DisasContext, base); 3775 3776 switch (dc->base.is_jmp) { 3777 case DISAS_NORETURN: 3778 /* 3779 * Most instructions should not use DISAS_NORETURN, as that suppresses 3780 * the handling of hflags normally done by gen_eob(). We can 3781 * get here: 3782 * - for exception and interrupts 3783 * - for jump optimization (which is disabled by INHIBIT_IRQ/RF/TF) 3784 * - for VMRUN because RF/TF handling for the host is done after vmexit, 3785 * and INHIBIT_IRQ is loaded from the VMCB 3786 * - for HLT/PAUSE/MWAIT to exit the main loop with specific EXCP_* values; 3787 * the helpers handle themselves the tasks normally done by gen_eob(). 3788 */ 3789 break; 3790 case DISAS_TOO_MANY: 3791 gen_update_cc_op(dc); 3792 gen_jmp_rel_csize(dc, 0, 0); 3793 break; 3794 case DISAS_EOB_NEXT: 3795 case DISAS_EOB_INHIBIT_IRQ: 3796 assert(dc->base.pc_next == dc->pc); 3797 gen_update_eip_cur(dc); 3798 /* fall through */ 3799 case DISAS_EOB_ONLY: 3800 case DISAS_EOB_RECHECK_TF: 3801 case DISAS_JUMP: 3802 gen_eob(dc, dc->base.is_jmp); 3803 break; 3804 default: 3805 g_assert_not_reached(); 3806 } 3807 } 3808 3809 static const TranslatorOps i386_tr_ops = { 3810 .init_disas_context = i386_tr_init_disas_context, 3811 .tb_start = i386_tr_tb_start, 3812 .insn_start = i386_tr_insn_start, 3813 .translate_insn = i386_tr_translate_insn, 3814 .tb_stop = i386_tr_tb_stop, 3815 }; 3816 3817 void x86_translate_code(CPUState *cpu, TranslationBlock *tb, 3818 int *max_insns, vaddr pc, void *host_pc) 3819 { 3820 DisasContext dc; 3821 3822 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); 3823 } 3824