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