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 * DISAS_EOB_INHIBIT_IRQ is a superset of DISAS_EOB_NEXT which 2051 * might have been set above. 2052 */ 2053 if (inhibit_irq) { 2054 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 2055 } 2056 } 2057 2058 static void gen_far_call(DisasContext *s) 2059 { 2060 TCGv_i32 new_cs = tcg_temp_new_i32(); 2061 tcg_gen_trunc_tl_i32(new_cs, s->T1); 2062 if (PE(s) && !VM86(s)) { 2063 gen_helper_lcall_protected(tcg_env, new_cs, s->T0, 2064 tcg_constant_i32(s->dflag - 1), 2065 eip_next_tl(s)); 2066 } else { 2067 TCGv_i32 new_eip = tcg_temp_new_i32(); 2068 tcg_gen_trunc_tl_i32(new_eip, s->T0); 2069 gen_helper_lcall_real(tcg_env, new_cs, new_eip, 2070 tcg_constant_i32(s->dflag - 1), 2071 eip_next_i32(s)); 2072 } 2073 s->base.is_jmp = DISAS_JUMP; 2074 } 2075 2076 static void gen_far_jmp(DisasContext *s) 2077 { 2078 if (PE(s) && !VM86(s)) { 2079 TCGv_i32 new_cs = tcg_temp_new_i32(); 2080 tcg_gen_trunc_tl_i32(new_cs, s->T1); 2081 gen_helper_ljmp_protected(tcg_env, new_cs, s->T0, 2082 eip_next_tl(s)); 2083 } else { 2084 gen_op_movl_seg_real(s, R_CS, s->T1); 2085 gen_op_jmp_v(s, s->T0); 2086 } 2087 s->base.is_jmp = DISAS_JUMP; 2088 } 2089 2090 static void gen_svm_check_intercept(DisasContext *s, uint32_t type) 2091 { 2092 /* no SVM activated; fast case */ 2093 if (likely(!GUEST(s))) { 2094 return; 2095 } 2096 gen_helper_svm_check_intercept(tcg_env, tcg_constant_i32(type)); 2097 } 2098 2099 static inline void gen_stack_update(DisasContext *s, int addend) 2100 { 2101 gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend); 2102 } 2103 2104 static void gen_lea_ss_ofs(DisasContext *s, TCGv dest, TCGv src, target_ulong offset) 2105 { 2106 if (offset) { 2107 tcg_gen_addi_tl(dest, src, offset); 2108 src = dest; 2109 } 2110 gen_lea_v_seg_dest(s, mo_stacksize(s), dest, src, R_SS, -1); 2111 } 2112 2113 /* Generate a push. It depends on ss32, addseg and dflag. */ 2114 static void gen_push_v(DisasContext *s, TCGv val) 2115 { 2116 MemOp d_ot = mo_pushpop(s, s->dflag); 2117 MemOp a_ot = mo_stacksize(s); 2118 int size = 1 << d_ot; 2119 TCGv new_esp = tcg_temp_new(); 2120 2121 tcg_gen_subi_tl(new_esp, cpu_regs[R_ESP], size); 2122 2123 /* Now reduce the value to the address size and apply SS base. */ 2124 gen_lea_ss_ofs(s, s->A0, new_esp, 0); 2125 gen_op_st_v(s, d_ot, val, s->A0); 2126 gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp); 2127 } 2128 2129 /* two step pop is necessary for precise exceptions */ 2130 static MemOp gen_pop_T0(DisasContext *s) 2131 { 2132 MemOp d_ot = mo_pushpop(s, s->dflag); 2133 2134 gen_lea_ss_ofs(s, s->T0, cpu_regs[R_ESP], 0); 2135 gen_op_ld_v(s, d_ot, s->T0, s->T0); 2136 2137 return d_ot; 2138 } 2139 2140 static inline void gen_pop_update(DisasContext *s, MemOp ot) 2141 { 2142 gen_stack_update(s, 1 << ot); 2143 } 2144 2145 static void gen_pusha(DisasContext *s) 2146 { 2147 MemOp d_ot = s->dflag; 2148 int size = 1 << d_ot; 2149 int i; 2150 2151 for (i = 0; i < 8; i++) { 2152 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], (i - 8) * size); 2153 gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0); 2154 } 2155 2156 gen_stack_update(s, -8 * size); 2157 } 2158 2159 static void gen_popa(DisasContext *s) 2160 { 2161 MemOp d_ot = s->dflag; 2162 int size = 1 << d_ot; 2163 int i; 2164 2165 for (i = 0; i < 8; i++) { 2166 /* ESP is not reloaded */ 2167 if (7 - i == R_ESP) { 2168 continue; 2169 } 2170 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], i * size); 2171 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2172 gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0); 2173 } 2174 2175 gen_stack_update(s, 8 * size); 2176 } 2177 2178 static void gen_enter(DisasContext *s, int esp_addend, int level) 2179 { 2180 MemOp d_ot = mo_pushpop(s, s->dflag); 2181 MemOp a_ot = mo_stacksize(s); 2182 int size = 1 << d_ot; 2183 2184 /* Push BP; compute FrameTemp into T1. */ 2185 tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size); 2186 gen_lea_ss_ofs(s, s->A0, s->T1, 0); 2187 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0); 2188 2189 level &= 31; 2190 if (level != 0) { 2191 int i; 2192 if (level > 1) { 2193 TCGv fp = tcg_temp_new(); 2194 2195 /* Copy level-1 pointers from the previous frame. */ 2196 for (i = 1; i < level; ++i) { 2197 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], -size * i); 2198 gen_op_ld_v(s, d_ot, fp, s->A0); 2199 2200 gen_lea_ss_ofs(s, s->A0, s->T1, -size * i); 2201 gen_op_st_v(s, d_ot, fp, s->A0); 2202 } 2203 } 2204 2205 /* Push the current FrameTemp as the last level. */ 2206 gen_lea_ss_ofs(s, s->A0, s->T1, -size * level); 2207 gen_op_st_v(s, d_ot, s->T1, s->A0); 2208 } 2209 2210 /* Copy the FrameTemp value to EBP. */ 2211 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T1); 2212 2213 /* Compute the final value of ESP. */ 2214 tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level); 2215 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2216 } 2217 2218 static void gen_leave(DisasContext *s) 2219 { 2220 MemOp d_ot = mo_pushpop(s, s->dflag); 2221 MemOp a_ot = mo_stacksize(s); 2222 2223 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], 0); 2224 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2225 2226 tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot); 2227 2228 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0); 2229 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2230 } 2231 2232 /* Similarly, except that the assumption here is that we don't decode 2233 the instruction at all -- either a missing opcode, an unimplemented 2234 feature, or just a bogus instruction stream. */ 2235 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) 2236 { 2237 gen_illegal_opcode(s); 2238 2239 if (qemu_loglevel_mask(LOG_UNIMP)) { 2240 FILE *logfile = qemu_log_trylock(); 2241 if (logfile) { 2242 target_ulong pc = s->base.pc_next, end = s->pc; 2243 2244 fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc); 2245 for (; pc < end; ++pc) { 2246 fprintf(logfile, " %02x", translator_ldub(env, &s->base, pc)); 2247 } 2248 fprintf(logfile, "\n"); 2249 qemu_log_unlock(logfile); 2250 } 2251 } 2252 } 2253 2254 /* an interrupt is different from an exception because of the 2255 privilege checks */ 2256 static void gen_interrupt(DisasContext *s, uint8_t intno) 2257 { 2258 gen_update_cc_op(s); 2259 gen_update_eip_cur(s); 2260 gen_helper_raise_interrupt(tcg_env, tcg_constant_i32(intno), 2261 cur_insn_len_i32(s)); 2262 s->base.is_jmp = DISAS_NORETURN; 2263 } 2264 2265 /* Clear BND registers during legacy branches. */ 2266 static void gen_bnd_jmp(DisasContext *s) 2267 { 2268 /* Clear the registers only if BND prefix is missing, MPX is enabled, 2269 and if the BNDREGs are known to be in use (non-zero) already. 2270 The helper itself will check BNDPRESERVE at runtime. */ 2271 if ((s->prefix & PREFIX_REPNZ) == 0 2272 && (s->flags & HF_MPX_EN_MASK) != 0 2273 && (s->flags & HF_MPX_IU_MASK) != 0) { 2274 gen_helper_bnd_jmp(tcg_env); 2275 } 2276 } 2277 2278 /* 2279 * Generate an end of block, including common tasks such as generating 2280 * single step traps, resetting the RF flag, and handling the interrupt 2281 * shadow. 2282 */ 2283 static void 2284 gen_eob(DisasContext *s, int mode) 2285 { 2286 bool inhibit_reset; 2287 2288 gen_update_cc_op(s); 2289 2290 /* If several instructions disable interrupts, only the first does it. */ 2291 inhibit_reset = false; 2292 if (s->flags & HF_INHIBIT_IRQ_MASK) { 2293 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); 2294 inhibit_reset = true; 2295 } else if (mode == DISAS_EOB_INHIBIT_IRQ) { 2296 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); 2297 } 2298 2299 if (s->flags & HF_RF_MASK) { 2300 gen_reset_eflags(s, RF_MASK); 2301 } 2302 if (mode == DISAS_EOB_RECHECK_TF) { 2303 gen_helper_rechecking_single_step(tcg_env); 2304 tcg_gen_exit_tb(NULL, 0); 2305 } else if ((s->flags & HF_TF_MASK) && mode != DISAS_EOB_INHIBIT_IRQ) { 2306 gen_helper_single_step(tcg_env); 2307 } else if (mode == DISAS_JUMP && 2308 /* give irqs a chance to happen */ 2309 !inhibit_reset) { 2310 tcg_gen_lookup_and_goto_ptr(); 2311 } else { 2312 tcg_gen_exit_tb(NULL, 0); 2313 } 2314 2315 s->base.is_jmp = DISAS_NORETURN; 2316 } 2317 2318 /* Jump to eip+diff, truncating the result to OT. */ 2319 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num) 2320 { 2321 bool use_goto_tb = s->jmp_opt; 2322 target_ulong mask = -1; 2323 target_ulong new_pc = s->pc + diff; 2324 target_ulong new_eip = new_pc - s->cs_base; 2325 2326 assert(!s->cc_op_dirty); 2327 2328 /* In 64-bit mode, operand size is fixed at 64 bits. */ 2329 if (!CODE64(s)) { 2330 if (ot == MO_16) { 2331 mask = 0xffff; 2332 if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) { 2333 use_goto_tb = false; 2334 } 2335 } else { 2336 mask = 0xffffffff; 2337 } 2338 } 2339 new_eip &= mask; 2340 2341 if (tb_cflags(s->base.tb) & CF_PCREL) { 2342 tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save); 2343 /* 2344 * If we can prove the branch does not leave the page and we have 2345 * no extra masking to apply (data16 branch in code32, see above), 2346 * then we have also proven that the addition does not wrap. 2347 */ 2348 if (!use_goto_tb || !translator_is_same_page(&s->base, new_pc)) { 2349 tcg_gen_andi_tl(cpu_eip, cpu_eip, mask); 2350 use_goto_tb = false; 2351 } 2352 } else if (!CODE64(s)) { 2353 new_pc = (uint32_t)(new_eip + s->cs_base); 2354 } 2355 2356 if (use_goto_tb && translator_use_goto_tb(&s->base, new_pc)) { 2357 /* jump to same page: we can use a direct jump */ 2358 tcg_gen_goto_tb(tb_num); 2359 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2360 tcg_gen_movi_tl(cpu_eip, new_eip); 2361 } 2362 tcg_gen_exit_tb(s->base.tb, tb_num); 2363 s->base.is_jmp = DISAS_NORETURN; 2364 } else { 2365 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2366 tcg_gen_movi_tl(cpu_eip, new_eip); 2367 } 2368 if (s->jmp_opt) { 2369 gen_eob(s, DISAS_JUMP); /* jump to another page */ 2370 } else { 2371 gen_eob(s, DISAS_EOB_ONLY); /* exit to main loop */ 2372 } 2373 } 2374 } 2375 2376 /* Jump to eip+diff, truncating to the current code size. */ 2377 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num) 2378 { 2379 /* CODE64 ignores the OT argument, so we need not consider it. */ 2380 gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num); 2381 } 2382 2383 static inline void gen_ldq_env_A0(DisasContext *s, int offset) 2384 { 2385 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2386 tcg_gen_st_i64(s->tmp1_i64, tcg_env, offset); 2387 } 2388 2389 static inline void gen_stq_env_A0(DisasContext *s, int offset) 2390 { 2391 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, offset); 2392 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2393 } 2394 2395 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align) 2396 { 2397 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2398 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2399 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2400 int mem_index = s->mem_index; 2401 TCGv_i128 t = tcg_temp_new_i128(); 2402 2403 tcg_gen_qemu_ld_i128(t, s->A0, mem_index, mop); 2404 tcg_gen_st_i128(t, tcg_env, offset); 2405 } 2406 2407 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align) 2408 { 2409 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2410 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2411 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2412 int mem_index = s->mem_index; 2413 TCGv_i128 t = tcg_temp_new_i128(); 2414 2415 tcg_gen_ld_i128(t, tcg_env, offset); 2416 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop); 2417 } 2418 2419 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align) 2420 { 2421 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2422 int mem_index = s->mem_index; 2423 TCGv_i128 t0 = tcg_temp_new_i128(); 2424 TCGv_i128 t1 = tcg_temp_new_i128(); 2425 TCGv a0_hi = tcg_temp_new(); 2426 2427 tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2428 tcg_gen_addi_tl(a0_hi, s->A0, 16); 2429 tcg_gen_qemu_ld_i128(t1, a0_hi, mem_index, mop); 2430 2431 tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2432 tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2433 } 2434 2435 static void gen_sty_env_A0(DisasContext *s, int offset, bool align) 2436 { 2437 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2438 int mem_index = s->mem_index; 2439 TCGv_i128 t = tcg_temp_new_i128(); 2440 TCGv a0_hi = tcg_temp_new(); 2441 2442 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2443 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2444 tcg_gen_addi_tl(a0_hi, s->A0, 16); 2445 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2446 tcg_gen_qemu_st_i128(t, a0_hi, mem_index, mop); 2447 } 2448 2449 #include "emit.c.inc" 2450 2451 static void gen_x87(DisasContext *s, X86DecodedInsn *decode) 2452 { 2453 bool update_fip = true; 2454 int b = decode->b; 2455 int modrm = s->modrm; 2456 int mod, rm, op; 2457 2458 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 2459 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 2460 /* XXX: what to do if illegal op ? */ 2461 gen_exception(s, EXCP07_PREX); 2462 return; 2463 } 2464 mod = (modrm >> 6) & 3; 2465 rm = modrm & 7; 2466 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 2467 if (mod != 3) { 2468 /* memory op */ 2469 TCGv ea = gen_lea_modrm_1(s, decode->mem, false); 2470 TCGv last_addr = tcg_temp_new(); 2471 bool update_fdp = true; 2472 2473 tcg_gen_mov_tl(last_addr, ea); 2474 gen_lea_v_seg(s, ea, decode->mem.def_seg, s->override); 2475 2476 switch (op) { 2477 case 0x00 ... 0x07: /* fxxxs */ 2478 case 0x10 ... 0x17: /* fixxxl */ 2479 case 0x20 ... 0x27: /* fxxxl */ 2480 case 0x30 ... 0x37: /* fixxx */ 2481 { 2482 int op1; 2483 op1 = op & 7; 2484 2485 switch (op >> 4) { 2486 case 0: 2487 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2488 s->mem_index, MO_LEUL); 2489 gen_helper_flds_FT0(tcg_env, s->tmp2_i32); 2490 break; 2491 case 1: 2492 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2493 s->mem_index, MO_LEUL); 2494 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2495 break; 2496 case 2: 2497 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2498 s->mem_index, MO_LEUQ); 2499 gen_helper_fldl_FT0(tcg_env, s->tmp1_i64); 2500 break; 2501 case 3: 2502 default: 2503 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2504 s->mem_index, MO_LESW); 2505 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2506 break; 2507 } 2508 2509 gen_helper_fp_arith_ST0_FT0(op1); 2510 if (op1 == 3) { 2511 /* fcomp needs pop */ 2512 gen_helper_fpop(tcg_env); 2513 } 2514 } 2515 break; 2516 case 0x08: /* flds */ 2517 case 0x0a: /* fsts */ 2518 case 0x0b: /* fstps */ 2519 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 2520 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 2521 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 2522 switch (op & 7) { 2523 case 0: 2524 switch (op >> 4) { 2525 case 0: 2526 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2527 s->mem_index, MO_LEUL); 2528 gen_helper_flds_ST0(tcg_env, s->tmp2_i32); 2529 break; 2530 case 1: 2531 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2532 s->mem_index, MO_LEUL); 2533 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2534 break; 2535 case 2: 2536 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2537 s->mem_index, MO_LEUQ); 2538 gen_helper_fldl_ST0(tcg_env, s->tmp1_i64); 2539 break; 2540 case 3: 2541 default: 2542 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2543 s->mem_index, MO_LESW); 2544 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2545 break; 2546 } 2547 break; 2548 case 1: 2549 /* XXX: the corresponding CPUID bit must be tested ! */ 2550 switch (op >> 4) { 2551 case 1: 2552 gen_helper_fisttl_ST0(s->tmp2_i32, tcg_env); 2553 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2554 s->mem_index, MO_LEUL); 2555 break; 2556 case 2: 2557 gen_helper_fisttll_ST0(s->tmp1_i64, tcg_env); 2558 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2559 s->mem_index, MO_LEUQ); 2560 break; 2561 case 3: 2562 default: 2563 gen_helper_fistt_ST0(s->tmp2_i32, tcg_env); 2564 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2565 s->mem_index, MO_LEUW); 2566 break; 2567 } 2568 gen_helper_fpop(tcg_env); 2569 break; 2570 default: 2571 switch (op >> 4) { 2572 case 0: 2573 gen_helper_fsts_ST0(s->tmp2_i32, tcg_env); 2574 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2575 s->mem_index, MO_LEUL); 2576 break; 2577 case 1: 2578 gen_helper_fistl_ST0(s->tmp2_i32, tcg_env); 2579 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2580 s->mem_index, MO_LEUL); 2581 break; 2582 case 2: 2583 gen_helper_fstl_ST0(s->tmp1_i64, tcg_env); 2584 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2585 s->mem_index, MO_LEUQ); 2586 break; 2587 case 3: 2588 default: 2589 gen_helper_fist_ST0(s->tmp2_i32, tcg_env); 2590 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2591 s->mem_index, MO_LEUW); 2592 break; 2593 } 2594 if ((op & 7) == 3) { 2595 gen_helper_fpop(tcg_env); 2596 } 2597 break; 2598 } 2599 break; 2600 case 0x0c: /* fldenv mem */ 2601 gen_helper_fldenv(tcg_env, s->A0, 2602 tcg_constant_i32(s->dflag - 1)); 2603 update_fip = update_fdp = false; 2604 break; 2605 case 0x0d: /* fldcw mem */ 2606 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2607 s->mem_index, MO_LEUW); 2608 gen_helper_fldcw(tcg_env, s->tmp2_i32); 2609 update_fip = update_fdp = false; 2610 break; 2611 case 0x0e: /* fnstenv mem */ 2612 gen_helper_fstenv(tcg_env, s->A0, 2613 tcg_constant_i32(s->dflag - 1)); 2614 update_fip = update_fdp = false; 2615 break; 2616 case 0x0f: /* fnstcw mem */ 2617 gen_helper_fnstcw(s->tmp2_i32, tcg_env); 2618 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2619 s->mem_index, MO_LEUW); 2620 update_fip = update_fdp = false; 2621 break; 2622 case 0x1d: /* fldt mem */ 2623 gen_helper_fldt_ST0(tcg_env, s->A0); 2624 break; 2625 case 0x1f: /* fstpt mem */ 2626 gen_helper_fstt_ST0(tcg_env, s->A0); 2627 gen_helper_fpop(tcg_env); 2628 break; 2629 case 0x2c: /* frstor mem */ 2630 gen_helper_frstor(tcg_env, s->A0, 2631 tcg_constant_i32(s->dflag - 1)); 2632 update_fip = update_fdp = false; 2633 break; 2634 case 0x2e: /* fnsave mem */ 2635 gen_helper_fsave(tcg_env, s->A0, 2636 tcg_constant_i32(s->dflag - 1)); 2637 update_fip = update_fdp = false; 2638 break; 2639 case 0x2f: /* fnstsw mem */ 2640 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2641 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2642 s->mem_index, MO_LEUW); 2643 update_fip = update_fdp = false; 2644 break; 2645 case 0x3c: /* fbld */ 2646 gen_helper_fbld_ST0(tcg_env, s->A0); 2647 break; 2648 case 0x3e: /* fbstp */ 2649 gen_helper_fbst_ST0(tcg_env, s->A0); 2650 gen_helper_fpop(tcg_env); 2651 break; 2652 case 0x3d: /* fildll */ 2653 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2654 s->mem_index, MO_LEUQ); 2655 gen_helper_fildll_ST0(tcg_env, s->tmp1_i64); 2656 break; 2657 case 0x3f: /* fistpll */ 2658 gen_helper_fistll_ST0(s->tmp1_i64, tcg_env); 2659 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2660 s->mem_index, MO_LEUQ); 2661 gen_helper_fpop(tcg_env); 2662 break; 2663 default: 2664 goto illegal_op; 2665 } 2666 2667 if (update_fdp) { 2668 int last_seg = s->override >= 0 ? s->override : decode->mem.def_seg; 2669 2670 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 2671 offsetof(CPUX86State, 2672 segs[last_seg].selector)); 2673 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 2674 offsetof(CPUX86State, fpds)); 2675 tcg_gen_st_tl(last_addr, tcg_env, 2676 offsetof(CPUX86State, fpdp)); 2677 } 2678 } else { 2679 /* register float ops */ 2680 int opreg = rm; 2681 2682 switch (op) { 2683 case 0x08: /* fld sti */ 2684 gen_helper_fpush(tcg_env); 2685 gen_helper_fmov_ST0_STN(tcg_env, 2686 tcg_constant_i32((opreg + 1) & 7)); 2687 break; 2688 case 0x09: /* fxchg sti */ 2689 case 0x29: /* fxchg4 sti, undocumented op */ 2690 case 0x39: /* fxchg7 sti, undocumented op */ 2691 gen_helper_fxchg_ST0_STN(tcg_env, tcg_constant_i32(opreg)); 2692 break; 2693 case 0x0a: /* grp d9/2 */ 2694 switch (rm) { 2695 case 0: /* fnop */ 2696 /* 2697 * check exceptions (FreeBSD FPU probe) 2698 * needs to be treated as I/O because of ferr_irq 2699 */ 2700 translator_io_start(&s->base); 2701 gen_helper_fwait(tcg_env); 2702 update_fip = false; 2703 break; 2704 default: 2705 goto illegal_op; 2706 } 2707 break; 2708 case 0x0c: /* grp d9/4 */ 2709 switch (rm) { 2710 case 0: /* fchs */ 2711 gen_helper_fchs_ST0(tcg_env); 2712 break; 2713 case 1: /* fabs */ 2714 gen_helper_fabs_ST0(tcg_env); 2715 break; 2716 case 4: /* ftst */ 2717 gen_helper_fldz_FT0(tcg_env); 2718 gen_helper_fcom_ST0_FT0(tcg_env); 2719 break; 2720 case 5: /* fxam */ 2721 gen_helper_fxam_ST0(tcg_env); 2722 break; 2723 default: 2724 goto illegal_op; 2725 } 2726 break; 2727 case 0x0d: /* grp d9/5 */ 2728 { 2729 switch (rm) { 2730 case 0: 2731 gen_helper_fpush(tcg_env); 2732 gen_helper_fld1_ST0(tcg_env); 2733 break; 2734 case 1: 2735 gen_helper_fpush(tcg_env); 2736 gen_helper_fldl2t_ST0(tcg_env); 2737 break; 2738 case 2: 2739 gen_helper_fpush(tcg_env); 2740 gen_helper_fldl2e_ST0(tcg_env); 2741 break; 2742 case 3: 2743 gen_helper_fpush(tcg_env); 2744 gen_helper_fldpi_ST0(tcg_env); 2745 break; 2746 case 4: 2747 gen_helper_fpush(tcg_env); 2748 gen_helper_fldlg2_ST0(tcg_env); 2749 break; 2750 case 5: 2751 gen_helper_fpush(tcg_env); 2752 gen_helper_fldln2_ST0(tcg_env); 2753 break; 2754 case 6: 2755 gen_helper_fpush(tcg_env); 2756 gen_helper_fldz_ST0(tcg_env); 2757 break; 2758 default: 2759 goto illegal_op; 2760 } 2761 } 2762 break; 2763 case 0x0e: /* grp d9/6 */ 2764 switch (rm) { 2765 case 0: /* f2xm1 */ 2766 gen_helper_f2xm1(tcg_env); 2767 break; 2768 case 1: /* fyl2x */ 2769 gen_helper_fyl2x(tcg_env); 2770 break; 2771 case 2: /* fptan */ 2772 gen_helper_fptan(tcg_env); 2773 break; 2774 case 3: /* fpatan */ 2775 gen_helper_fpatan(tcg_env); 2776 break; 2777 case 4: /* fxtract */ 2778 gen_helper_fxtract(tcg_env); 2779 break; 2780 case 5: /* fprem1 */ 2781 gen_helper_fprem1(tcg_env); 2782 break; 2783 case 6: /* fdecstp */ 2784 gen_helper_fdecstp(tcg_env); 2785 break; 2786 default: 2787 case 7: /* fincstp */ 2788 gen_helper_fincstp(tcg_env); 2789 break; 2790 } 2791 break; 2792 case 0x0f: /* grp d9/7 */ 2793 switch (rm) { 2794 case 0: /* fprem */ 2795 gen_helper_fprem(tcg_env); 2796 break; 2797 case 1: /* fyl2xp1 */ 2798 gen_helper_fyl2xp1(tcg_env); 2799 break; 2800 case 2: /* fsqrt */ 2801 gen_helper_fsqrt(tcg_env); 2802 break; 2803 case 3: /* fsincos */ 2804 gen_helper_fsincos(tcg_env); 2805 break; 2806 case 5: /* fscale */ 2807 gen_helper_fscale(tcg_env); 2808 break; 2809 case 4: /* frndint */ 2810 gen_helper_frndint(tcg_env); 2811 break; 2812 case 6: /* fsin */ 2813 gen_helper_fsin(tcg_env); 2814 break; 2815 default: 2816 case 7: /* fcos */ 2817 gen_helper_fcos(tcg_env); 2818 break; 2819 } 2820 break; 2821 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 2822 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 2823 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 2824 { 2825 int op1; 2826 2827 op1 = op & 7; 2828 if (op >= 0x20) { 2829 gen_helper_fp_arith_STN_ST0(op1, opreg); 2830 if (op >= 0x30) { 2831 gen_helper_fpop(tcg_env); 2832 } 2833 } else { 2834 gen_helper_fmov_FT0_STN(tcg_env, 2835 tcg_constant_i32(opreg)); 2836 gen_helper_fp_arith_ST0_FT0(op1); 2837 } 2838 } 2839 break; 2840 case 0x02: /* fcom */ 2841 case 0x22: /* fcom2, undocumented op */ 2842 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2843 gen_helper_fcom_ST0_FT0(tcg_env); 2844 break; 2845 case 0x03: /* fcomp */ 2846 case 0x23: /* fcomp3, undocumented op */ 2847 case 0x32: /* fcomp5, undocumented op */ 2848 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2849 gen_helper_fcom_ST0_FT0(tcg_env); 2850 gen_helper_fpop(tcg_env); 2851 break; 2852 case 0x15: /* da/5 */ 2853 switch (rm) { 2854 case 1: /* fucompp */ 2855 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2856 gen_helper_fucom_ST0_FT0(tcg_env); 2857 gen_helper_fpop(tcg_env); 2858 gen_helper_fpop(tcg_env); 2859 break; 2860 default: 2861 goto illegal_op; 2862 } 2863 break; 2864 case 0x1c: 2865 switch (rm) { 2866 case 0: /* feni (287 only, just do nop here) */ 2867 break; 2868 case 1: /* fdisi (287 only, just do nop here) */ 2869 break; 2870 case 2: /* fclex */ 2871 gen_helper_fclex(tcg_env); 2872 update_fip = false; 2873 break; 2874 case 3: /* fninit */ 2875 gen_helper_fninit(tcg_env); 2876 update_fip = false; 2877 break; 2878 case 4: /* fsetpm (287 only, just do nop here) */ 2879 break; 2880 default: 2881 goto illegal_op; 2882 } 2883 break; 2884 case 0x1d: /* fucomi */ 2885 if (!(s->cpuid_features & CPUID_CMOV)) { 2886 goto illegal_op; 2887 } 2888 gen_update_cc_op(s); 2889 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2890 gen_helper_fucomi_ST0_FT0(tcg_env); 2891 assume_cc_op(s, CC_OP_EFLAGS); 2892 break; 2893 case 0x1e: /* fcomi */ 2894 if (!(s->cpuid_features & CPUID_CMOV)) { 2895 goto illegal_op; 2896 } 2897 gen_update_cc_op(s); 2898 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2899 gen_helper_fcomi_ST0_FT0(tcg_env); 2900 assume_cc_op(s, CC_OP_EFLAGS); 2901 break; 2902 case 0x28: /* ffree sti */ 2903 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2904 break; 2905 case 0x2a: /* fst sti */ 2906 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2907 break; 2908 case 0x2b: /* fstp sti */ 2909 case 0x0b: /* fstp1 sti, undocumented op */ 2910 case 0x3a: /* fstp8 sti, undocumented op */ 2911 case 0x3b: /* fstp9 sti, undocumented op */ 2912 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2913 gen_helper_fpop(tcg_env); 2914 break; 2915 case 0x2c: /* fucom st(i) */ 2916 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2917 gen_helper_fucom_ST0_FT0(tcg_env); 2918 break; 2919 case 0x2d: /* fucomp st(i) */ 2920 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2921 gen_helper_fucom_ST0_FT0(tcg_env); 2922 gen_helper_fpop(tcg_env); 2923 break; 2924 case 0x33: /* de/3 */ 2925 switch (rm) { 2926 case 1: /* fcompp */ 2927 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2928 gen_helper_fcom_ST0_FT0(tcg_env); 2929 gen_helper_fpop(tcg_env); 2930 gen_helper_fpop(tcg_env); 2931 break; 2932 default: 2933 goto illegal_op; 2934 } 2935 break; 2936 case 0x38: /* ffreep sti, undocumented op */ 2937 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2938 gen_helper_fpop(tcg_env); 2939 break; 2940 case 0x3c: /* df/4 */ 2941 switch (rm) { 2942 case 0: 2943 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2944 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 2945 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 2946 break; 2947 default: 2948 goto illegal_op; 2949 } 2950 break; 2951 case 0x3d: /* fucomip */ 2952 if (!(s->cpuid_features & CPUID_CMOV)) { 2953 goto illegal_op; 2954 } 2955 gen_update_cc_op(s); 2956 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2957 gen_helper_fucomi_ST0_FT0(tcg_env); 2958 gen_helper_fpop(tcg_env); 2959 assume_cc_op(s, CC_OP_EFLAGS); 2960 break; 2961 case 0x3e: /* fcomip */ 2962 if (!(s->cpuid_features & CPUID_CMOV)) { 2963 goto illegal_op; 2964 } 2965 gen_update_cc_op(s); 2966 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2967 gen_helper_fcomi_ST0_FT0(tcg_env); 2968 gen_helper_fpop(tcg_env); 2969 assume_cc_op(s, CC_OP_EFLAGS); 2970 break; 2971 case 0x10 ... 0x13: /* fcmovxx */ 2972 case 0x18 ... 0x1b: 2973 { 2974 int op1; 2975 TCGLabel *l1; 2976 static const uint8_t fcmov_cc[8] = { 2977 (JCC_B << 1), 2978 (JCC_Z << 1), 2979 (JCC_BE << 1), 2980 (JCC_P << 1), 2981 }; 2982 2983 if (!(s->cpuid_features & CPUID_CMOV)) { 2984 goto illegal_op; 2985 } 2986 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 2987 l1 = gen_new_label(); 2988 gen_jcc_noeob(s, op1, l1); 2989 gen_helper_fmov_ST0_STN(tcg_env, 2990 tcg_constant_i32(opreg)); 2991 gen_set_label(l1); 2992 } 2993 break; 2994 default: 2995 goto illegal_op; 2996 } 2997 } 2998 2999 if (update_fip) { 3000 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 3001 offsetof(CPUX86State, segs[R_CS].selector)); 3002 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 3003 offsetof(CPUX86State, fpcs)); 3004 tcg_gen_st_tl(eip_cur_tl(s), 3005 tcg_env, offsetof(CPUX86State, fpip)); 3006 } 3007 return; 3008 3009 illegal_op: 3010 gen_illegal_opcode(s); 3011 } 3012 3013 static void gen_multi0F(DisasContext *s, X86DecodedInsn *decode) 3014 { 3015 int prefixes = s->prefix; 3016 MemOp dflag = s->dflag; 3017 int b = decode->b + 0x100; 3018 int modrm = s->modrm; 3019 MemOp ot; 3020 int reg, rm, mod, op; 3021 3022 /* now check op code */ 3023 switch (b) { 3024 case 0x1c7: /* RDSEED, RDPID with f3 prefix */ 3025 mod = (modrm >> 6) & 3; 3026 switch ((modrm >> 3) & 7) { 3027 case 7: 3028 if (mod != 3 || 3029 (s->prefix & PREFIX_REPNZ)) { 3030 goto illegal_op; 3031 } 3032 if (s->prefix & PREFIX_REPZ) { 3033 if (!(s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_RDPID)) { 3034 goto illegal_op; 3035 } 3036 gen_helper_rdpid(s->T0, tcg_env); 3037 rm = (modrm & 7) | REX_B(s); 3038 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3039 break; 3040 } else { 3041 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) { 3042 goto illegal_op; 3043 } 3044 goto do_rdrand; 3045 } 3046 3047 case 6: /* RDRAND */ 3048 if (mod != 3 || 3049 (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) || 3050 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { 3051 goto illegal_op; 3052 } 3053 do_rdrand: 3054 translator_io_start(&s->base); 3055 gen_helper_rdrand(s->T0, tcg_env); 3056 rm = (modrm & 7) | REX_B(s); 3057 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3058 assume_cc_op(s, CC_OP_EFLAGS); 3059 break; 3060 3061 default: 3062 goto illegal_op; 3063 } 3064 break; 3065 3066 case 0x100: 3067 mod = (modrm >> 6) & 3; 3068 op = (modrm >> 3) & 7; 3069 switch(op) { 3070 case 0: /* sldt */ 3071 if (!PE(s) || VM86(s)) 3072 goto illegal_op; 3073 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3074 break; 3075 } 3076 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ); 3077 tcg_gen_ld32u_tl(s->T0, tcg_env, 3078 offsetof(CPUX86State, ldt.selector)); 3079 ot = mod == 3 ? dflag : MO_16; 3080 gen_st_modrm(s, decode, ot); 3081 break; 3082 case 2: /* lldt */ 3083 if (!PE(s) || VM86(s)) 3084 goto illegal_op; 3085 if (check_cpl0(s)) { 3086 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE); 3087 gen_ld_modrm(s, decode, MO_16); 3088 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3089 gen_helper_lldt(tcg_env, s->tmp2_i32); 3090 } 3091 break; 3092 case 1: /* str */ 3093 if (!PE(s) || VM86(s)) 3094 goto illegal_op; 3095 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3096 break; 3097 } 3098 gen_svm_check_intercept(s, SVM_EXIT_TR_READ); 3099 tcg_gen_ld32u_tl(s->T0, tcg_env, 3100 offsetof(CPUX86State, tr.selector)); 3101 ot = mod == 3 ? dflag : MO_16; 3102 gen_st_modrm(s, decode, ot); 3103 break; 3104 case 3: /* ltr */ 3105 if (!PE(s) || VM86(s)) 3106 goto illegal_op; 3107 if (check_cpl0(s)) { 3108 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE); 3109 gen_ld_modrm(s, decode, MO_16); 3110 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3111 gen_helper_ltr(tcg_env, s->tmp2_i32); 3112 } 3113 break; 3114 case 4: /* verr */ 3115 case 5: /* verw */ 3116 if (!PE(s) || VM86(s)) 3117 goto illegal_op; 3118 gen_ld_modrm(s, decode, MO_16); 3119 gen_update_cc_op(s); 3120 if (op == 4) { 3121 gen_helper_verr(tcg_env, s->T0); 3122 } else { 3123 gen_helper_verw(tcg_env, s->T0); 3124 } 3125 assume_cc_op(s, CC_OP_EFLAGS); 3126 break; 3127 default: 3128 goto illegal_op; 3129 } 3130 break; 3131 3132 case 0x101: 3133 switch (modrm) { 3134 CASE_MODRM_MEM_OP(0): /* sgdt */ 3135 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3136 break; 3137 } 3138 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ); 3139 gen_lea_modrm(s, decode); 3140 tcg_gen_ld32u_tl(s->T0, 3141 tcg_env, offsetof(CPUX86State, gdt.limit)); 3142 gen_op_st_v(s, MO_16, s->T0, s->A0); 3143 gen_add_A0_im(s, 2); 3144 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3145 /* 3146 * NB: Despite a confusing description in Intel CPU documentation, 3147 * all 32-bits are written regardless of operand size. 3148 */ 3149 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3150 break; 3151 3152 case 0xc8: /* monitor */ 3153 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3154 goto illegal_op; 3155 } 3156 gen_update_cc_op(s); 3157 gen_update_eip_cur(s); 3158 gen_lea_v_seg(s, cpu_regs[R_EAX], R_DS, s->override); 3159 gen_helper_monitor(tcg_env, s->A0); 3160 break; 3161 3162 case 0xc9: /* mwait */ 3163 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3164 goto illegal_op; 3165 } 3166 gen_update_cc_op(s); 3167 gen_update_eip_cur(s); 3168 gen_helper_mwait(tcg_env, cur_insn_len_i32(s)); 3169 s->base.is_jmp = DISAS_NORETURN; 3170 break; 3171 3172 case 0xca: /* clac */ 3173 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3174 || CPL(s) != 0) { 3175 goto illegal_op; 3176 } 3177 gen_reset_eflags(s, AC_MASK); 3178 s->base.is_jmp = DISAS_EOB_NEXT; 3179 break; 3180 3181 case 0xcb: /* stac */ 3182 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3183 || CPL(s) != 0) { 3184 goto illegal_op; 3185 } 3186 gen_set_eflags(s, AC_MASK); 3187 s->base.is_jmp = DISAS_EOB_NEXT; 3188 break; 3189 3190 CASE_MODRM_MEM_OP(1): /* sidt */ 3191 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3192 break; 3193 } 3194 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ); 3195 gen_lea_modrm(s, decode); 3196 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.limit)); 3197 gen_op_st_v(s, MO_16, s->T0, s->A0); 3198 gen_add_A0_im(s, 2); 3199 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3200 /* 3201 * NB: Despite a confusing description in Intel CPU documentation, 3202 * all 32-bits are written regardless of operand size. 3203 */ 3204 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3205 break; 3206 3207 case 0xd0: /* xgetbv */ 3208 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3209 || (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { 3210 goto illegal_op; 3211 } 3212 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3213 gen_helper_xgetbv(s->tmp1_i64, tcg_env, s->tmp2_i32); 3214 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3215 break; 3216 3217 case 0xd1: /* xsetbv */ 3218 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3219 || (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { 3220 goto illegal_op; 3221 } 3222 gen_svm_check_intercept(s, SVM_EXIT_XSETBV); 3223 if (!check_cpl0(s)) { 3224 break; 3225 } 3226 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3227 cpu_regs[R_EDX]); 3228 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3229 gen_helper_xsetbv(tcg_env, s->tmp2_i32, s->tmp1_i64); 3230 /* End TB because translation flags may change. */ 3231 s->base.is_jmp = DISAS_EOB_NEXT; 3232 break; 3233 3234 case 0xd8: /* VMRUN */ 3235 if (!SVME(s) || !PE(s)) { 3236 goto illegal_op; 3237 } 3238 if (!check_cpl0(s)) { 3239 break; 3240 } 3241 gen_update_cc_op(s); 3242 gen_update_eip_cur(s); 3243 /* 3244 * Reloads INHIBIT_IRQ mask as well as TF and RF with guest state. 3245 * The usual gen_eob() handling is performed on vmexit after 3246 * host state is reloaded. 3247 */ 3248 gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1), 3249 cur_insn_len_i32(s)); 3250 tcg_gen_exit_tb(NULL, 0); 3251 s->base.is_jmp = DISAS_NORETURN; 3252 break; 3253 3254 case 0xd9: /* VMMCALL */ 3255 if (!SVME(s)) { 3256 goto illegal_op; 3257 } 3258 gen_update_cc_op(s); 3259 gen_update_eip_cur(s); 3260 gen_helper_vmmcall(tcg_env); 3261 break; 3262 3263 case 0xda: /* VMLOAD */ 3264 if (!SVME(s) || !PE(s)) { 3265 goto illegal_op; 3266 } 3267 if (!check_cpl0(s)) { 3268 break; 3269 } 3270 gen_update_cc_op(s); 3271 gen_update_eip_cur(s); 3272 gen_helper_vmload(tcg_env, tcg_constant_i32(s->aflag - 1)); 3273 break; 3274 3275 case 0xdb: /* VMSAVE */ 3276 if (!SVME(s) || !PE(s)) { 3277 goto illegal_op; 3278 } 3279 if (!check_cpl0(s)) { 3280 break; 3281 } 3282 gen_update_cc_op(s); 3283 gen_update_eip_cur(s); 3284 gen_helper_vmsave(tcg_env, tcg_constant_i32(s->aflag - 1)); 3285 break; 3286 3287 case 0xdc: /* STGI */ 3288 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3289 || !PE(s)) { 3290 goto illegal_op; 3291 } 3292 if (!check_cpl0(s)) { 3293 break; 3294 } 3295 gen_update_cc_op(s); 3296 gen_helper_stgi(tcg_env); 3297 s->base.is_jmp = DISAS_EOB_NEXT; 3298 break; 3299 3300 case 0xdd: /* CLGI */ 3301 if (!SVME(s) || !PE(s)) { 3302 goto illegal_op; 3303 } 3304 if (!check_cpl0(s)) { 3305 break; 3306 } 3307 gen_update_cc_op(s); 3308 gen_update_eip_cur(s); 3309 gen_helper_clgi(tcg_env); 3310 break; 3311 3312 case 0xde: /* SKINIT */ 3313 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3314 || !PE(s)) { 3315 goto illegal_op; 3316 } 3317 gen_svm_check_intercept(s, SVM_EXIT_SKINIT); 3318 /* If not intercepted, not implemented -- raise #UD. */ 3319 goto illegal_op; 3320 3321 case 0xdf: /* INVLPGA */ 3322 if (!SVME(s) || !PE(s)) { 3323 goto illegal_op; 3324 } 3325 if (!check_cpl0(s)) { 3326 break; 3327 } 3328 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA); 3329 if (s->aflag == MO_64) { 3330 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 3331 } else { 3332 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]); 3333 } 3334 gen_helper_flush_page(tcg_env, s->A0); 3335 s->base.is_jmp = DISAS_EOB_NEXT; 3336 break; 3337 3338 CASE_MODRM_MEM_OP(2): /* lgdt */ 3339 if (!check_cpl0(s)) { 3340 break; 3341 } 3342 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE); 3343 gen_lea_modrm(s, decode); 3344 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3345 gen_add_A0_im(s, 2); 3346 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3347 if (dflag == MO_16) { 3348 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3349 } 3350 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3351 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, gdt.limit)); 3352 break; 3353 3354 CASE_MODRM_MEM_OP(3): /* lidt */ 3355 if (!check_cpl0(s)) { 3356 break; 3357 } 3358 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE); 3359 gen_lea_modrm(s, decode); 3360 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3361 gen_add_A0_im(s, 2); 3362 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3363 if (dflag == MO_16) { 3364 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3365 } 3366 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3367 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, idt.limit)); 3368 break; 3369 3370 CASE_MODRM_OP(4): /* smsw */ 3371 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3372 break; 3373 } 3374 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0); 3375 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, cr[0])); 3376 /* 3377 * In 32-bit mode, the higher 16 bits of the destination 3378 * register are undefined. In practice CR0[31:0] is stored 3379 * just like in 64-bit mode. 3380 */ 3381 mod = (modrm >> 6) & 3; 3382 ot = (mod != 3 ? MO_16 : s->dflag); 3383 gen_st_modrm(s, decode, ot); 3384 break; 3385 case 0xee: /* rdpkru */ 3386 if (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ)) { 3387 goto illegal_op; 3388 } 3389 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3390 gen_helper_rdpkru(s->tmp1_i64, tcg_env, s->tmp2_i32); 3391 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3392 break; 3393 case 0xef: /* wrpkru */ 3394 if (s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ)) { 3395 goto illegal_op; 3396 } 3397 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3398 cpu_regs[R_EDX]); 3399 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3400 gen_helper_wrpkru(tcg_env, s->tmp2_i32, s->tmp1_i64); 3401 break; 3402 3403 CASE_MODRM_OP(6): /* lmsw */ 3404 if (!check_cpl0(s)) { 3405 break; 3406 } 3407 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 3408 gen_ld_modrm(s, decode, MO_16); 3409 /* 3410 * Only the 4 lower bits of CR0 are modified. 3411 * PE cannot be set to zero if already set to one. 3412 */ 3413 tcg_gen_ld_tl(s->T1, tcg_env, offsetof(CPUX86State, cr[0])); 3414 tcg_gen_andi_tl(s->T0, s->T0, 0xf); 3415 tcg_gen_andi_tl(s->T1, s->T1, ~0xe); 3416 tcg_gen_or_tl(s->T0, s->T0, s->T1); 3417 gen_helper_write_crN(tcg_env, tcg_constant_i32(0), s->T0); 3418 s->base.is_jmp = DISAS_EOB_NEXT; 3419 break; 3420 3421 CASE_MODRM_MEM_OP(7): /* invlpg */ 3422 if (!check_cpl0(s)) { 3423 break; 3424 } 3425 gen_svm_check_intercept(s, SVM_EXIT_INVLPG); 3426 gen_lea_modrm(s, decode); 3427 gen_helper_flush_page(tcg_env, s->A0); 3428 s->base.is_jmp = DISAS_EOB_NEXT; 3429 break; 3430 3431 case 0xf8: /* swapgs */ 3432 #ifdef TARGET_X86_64 3433 if (CODE64(s)) { 3434 if (check_cpl0(s)) { 3435 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]); 3436 tcg_gen_ld_tl(cpu_seg_base[R_GS], tcg_env, 3437 offsetof(CPUX86State, kernelgsbase)); 3438 tcg_gen_st_tl(s->T0, tcg_env, 3439 offsetof(CPUX86State, kernelgsbase)); 3440 } 3441 break; 3442 } 3443 #endif 3444 goto illegal_op; 3445 3446 case 0xf9: /* rdtscp */ 3447 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) { 3448 goto illegal_op; 3449 } 3450 gen_update_cc_op(s); 3451 gen_update_eip_cur(s); 3452 translator_io_start(&s->base); 3453 gen_helper_rdtsc(tcg_env); 3454 gen_helper_rdpid(s->T0, tcg_env); 3455 gen_op_mov_reg_v(s, dflag, R_ECX, s->T0); 3456 break; 3457 3458 default: 3459 goto illegal_op; 3460 } 3461 break; 3462 3463 case 0x11a: 3464 if (s->flags & HF_MPX_EN_MASK) { 3465 mod = (modrm >> 6) & 3; 3466 reg = ((modrm >> 3) & 7) | REX_R(s); 3467 if (prefixes & PREFIX_REPZ) { 3468 /* bndcl */ 3469 if (reg >= 4 3470 || s->aflag == MO_16) { 3471 goto illegal_op; 3472 } 3473 gen_bndck(s, decode, TCG_COND_LTU, cpu_bndl[reg]); 3474 } else if (prefixes & PREFIX_REPNZ) { 3475 /* bndcu */ 3476 if (reg >= 4 3477 || s->aflag == MO_16) { 3478 goto illegal_op; 3479 } 3480 TCGv_i64 notu = tcg_temp_new_i64(); 3481 tcg_gen_not_i64(notu, cpu_bndu[reg]); 3482 gen_bndck(s, decode, TCG_COND_GTU, notu); 3483 } else if (prefixes & PREFIX_DATA) { 3484 /* bndmov -- from reg/mem */ 3485 if (reg >= 4 || s->aflag == MO_16) { 3486 goto illegal_op; 3487 } 3488 if (mod == 3) { 3489 int reg2 = (modrm & 7) | REX_B(s); 3490 if (reg2 >= 4) { 3491 goto illegal_op; 3492 } 3493 if (s->flags & HF_MPX_IU_MASK) { 3494 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]); 3495 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]); 3496 } 3497 } else { 3498 gen_lea_modrm(s, decode); 3499 if (CODE64(s)) { 3500 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 3501 s->mem_index, MO_LEUQ); 3502 tcg_gen_addi_tl(s->A0, s->A0, 8); 3503 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 3504 s->mem_index, MO_LEUQ); 3505 } else { 3506 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 3507 s->mem_index, MO_LEUL); 3508 tcg_gen_addi_tl(s->A0, s->A0, 4); 3509 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 3510 s->mem_index, MO_LEUL); 3511 } 3512 /* bnd registers are now in-use */ 3513 gen_set_hflag(s, HF_MPX_IU_MASK); 3514 } 3515 } else if (mod != 3) { 3516 /* bndldx */ 3517 AddressParts a = decode->mem; 3518 if (reg >= 4 3519 || s->aflag == MO_16 3520 || a.base < -1) { 3521 goto illegal_op; 3522 } 3523 if (a.base >= 0) { 3524 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 3525 } else { 3526 tcg_gen_movi_tl(s->A0, 0); 3527 } 3528 gen_lea_v_seg(s, s->A0, a.def_seg, s->override); 3529 if (a.index >= 0) { 3530 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 3531 } else { 3532 tcg_gen_movi_tl(s->T0, 0); 3533 } 3534 if (CODE64(s)) { 3535 gen_helper_bndldx64(cpu_bndl[reg], tcg_env, s->A0, s->T0); 3536 tcg_gen_ld_i64(cpu_bndu[reg], tcg_env, 3537 offsetof(CPUX86State, mmx_t0.MMX_Q(0))); 3538 } else { 3539 gen_helper_bndldx32(cpu_bndu[reg], tcg_env, s->A0, s->T0); 3540 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]); 3541 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32); 3542 } 3543 gen_set_hflag(s, HF_MPX_IU_MASK); 3544 } 3545 } 3546 break; 3547 case 0x11b: 3548 if (s->flags & HF_MPX_EN_MASK) { 3549 mod = (modrm >> 6) & 3; 3550 reg = ((modrm >> 3) & 7) | REX_R(s); 3551 if (mod != 3 && (prefixes & PREFIX_REPZ)) { 3552 /* bndmk */ 3553 if (reg >= 4 3554 || s->aflag == MO_16) { 3555 goto illegal_op; 3556 } 3557 AddressParts a = decode->mem; 3558 if (a.base >= 0) { 3559 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]); 3560 if (!CODE64(s)) { 3561 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]); 3562 } 3563 } else if (a.base == -1) { 3564 /* no base register has lower bound of 0 */ 3565 tcg_gen_movi_i64(cpu_bndl[reg], 0); 3566 } else { 3567 /* rip-relative generates #ud */ 3568 goto illegal_op; 3569 } 3570 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, decode->mem, false)); 3571 if (!CODE64(s)) { 3572 tcg_gen_ext32u_tl(s->A0, s->A0); 3573 } 3574 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0); 3575 /* bnd registers are now in-use */ 3576 gen_set_hflag(s, HF_MPX_IU_MASK); 3577 break; 3578 } else if (prefixes & PREFIX_REPNZ) { 3579 /* bndcn */ 3580 if (reg >= 4 3581 || s->aflag == MO_16) { 3582 goto illegal_op; 3583 } 3584 gen_bndck(s, decode, TCG_COND_GTU, cpu_bndu[reg]); 3585 } else if (prefixes & PREFIX_DATA) { 3586 /* bndmov -- to reg/mem */ 3587 if (reg >= 4 || s->aflag == MO_16) { 3588 goto illegal_op; 3589 } 3590 if (mod == 3) { 3591 int reg2 = (modrm & 7) | REX_B(s); 3592 if (reg2 >= 4) { 3593 goto illegal_op; 3594 } 3595 if (s->flags & HF_MPX_IU_MASK) { 3596 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]); 3597 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]); 3598 } 3599 } else { 3600 gen_lea_modrm(s, decode); 3601 if (CODE64(s)) { 3602 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 3603 s->mem_index, MO_LEUQ); 3604 tcg_gen_addi_tl(s->A0, s->A0, 8); 3605 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 3606 s->mem_index, MO_LEUQ); 3607 } else { 3608 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 3609 s->mem_index, MO_LEUL); 3610 tcg_gen_addi_tl(s->A0, s->A0, 4); 3611 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 3612 s->mem_index, MO_LEUL); 3613 } 3614 } 3615 } else if (mod != 3) { 3616 /* bndstx */ 3617 AddressParts a = decode->mem; 3618 if (reg >= 4 3619 || s->aflag == MO_16 3620 || a.base < -1) { 3621 goto illegal_op; 3622 } 3623 if (a.base >= 0) { 3624 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 3625 } else { 3626 tcg_gen_movi_tl(s->A0, 0); 3627 } 3628 gen_lea_v_seg(s, s->A0, a.def_seg, s->override); 3629 if (a.index >= 0) { 3630 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 3631 } else { 3632 tcg_gen_movi_tl(s->T0, 0); 3633 } 3634 if (CODE64(s)) { 3635 gen_helper_bndstx64(tcg_env, s->A0, s->T0, 3636 cpu_bndl[reg], cpu_bndu[reg]); 3637 } else { 3638 gen_helper_bndstx32(tcg_env, s->A0, s->T0, 3639 cpu_bndl[reg], cpu_bndu[reg]); 3640 } 3641 } 3642 } 3643 break; 3644 default: 3645 g_assert_not_reached(); 3646 } 3647 return; 3648 illegal_op: 3649 gen_illegal_opcode(s); 3650 } 3651 3652 #include "decode-new.c.inc" 3653 3654 void tcg_x86_init(void) 3655 { 3656 static const char reg_names[CPU_NB_REGS][4] = { 3657 #ifdef TARGET_X86_64 3658 [R_EAX] = "rax", 3659 [R_EBX] = "rbx", 3660 [R_ECX] = "rcx", 3661 [R_EDX] = "rdx", 3662 [R_ESI] = "rsi", 3663 [R_EDI] = "rdi", 3664 [R_EBP] = "rbp", 3665 [R_ESP] = "rsp", 3666 [8] = "r8", 3667 [9] = "r9", 3668 [10] = "r10", 3669 [11] = "r11", 3670 [12] = "r12", 3671 [13] = "r13", 3672 [14] = "r14", 3673 [15] = "r15", 3674 #else 3675 [R_EAX] = "eax", 3676 [R_EBX] = "ebx", 3677 [R_ECX] = "ecx", 3678 [R_EDX] = "edx", 3679 [R_ESI] = "esi", 3680 [R_EDI] = "edi", 3681 [R_EBP] = "ebp", 3682 [R_ESP] = "esp", 3683 #endif 3684 }; 3685 static const char eip_name[] = { 3686 #ifdef TARGET_X86_64 3687 "rip" 3688 #else 3689 "eip" 3690 #endif 3691 }; 3692 static const char seg_base_names[6][8] = { 3693 [R_CS] = "cs_base", 3694 [R_DS] = "ds_base", 3695 [R_ES] = "es_base", 3696 [R_FS] = "fs_base", 3697 [R_GS] = "gs_base", 3698 [R_SS] = "ss_base", 3699 }; 3700 static const char bnd_regl_names[4][8] = { 3701 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb" 3702 }; 3703 static const char bnd_regu_names[4][8] = { 3704 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" 3705 }; 3706 int i; 3707 3708 cpu_cc_op = tcg_global_mem_new_i32(tcg_env, 3709 offsetof(CPUX86State, cc_op), "cc_op"); 3710 cpu_cc_dst = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_dst), 3711 "cc_dst"); 3712 cpu_cc_src = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src), 3713 "cc_src"); 3714 cpu_cc_src2 = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src2), 3715 "cc_src2"); 3716 cpu_eip = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, eip), eip_name); 3717 3718 for (i = 0; i < CPU_NB_REGS; ++i) { 3719 cpu_regs[i] = tcg_global_mem_new(tcg_env, 3720 offsetof(CPUX86State, regs[i]), 3721 reg_names[i]); 3722 } 3723 3724 for (i = 0; i < 6; ++i) { 3725 cpu_seg_base[i] 3726 = tcg_global_mem_new(tcg_env, 3727 offsetof(CPUX86State, segs[i].base), 3728 seg_base_names[i]); 3729 } 3730 3731 for (i = 0; i < 4; ++i) { 3732 cpu_bndl[i] 3733 = tcg_global_mem_new_i64(tcg_env, 3734 offsetof(CPUX86State, bnd_regs[i].lb), 3735 bnd_regl_names[i]); 3736 cpu_bndu[i] 3737 = tcg_global_mem_new_i64(tcg_env, 3738 offsetof(CPUX86State, bnd_regs[i].ub), 3739 bnd_regu_names[i]); 3740 } 3741 } 3742 3743 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 3744 { 3745 DisasContext *dc = container_of(dcbase, DisasContext, base); 3746 CPUX86State *env = cpu_env(cpu); 3747 uint32_t flags = dc->base.tb->flags; 3748 uint32_t cflags = tb_cflags(dc->base.tb); 3749 int cpl = (flags >> HF_CPL_SHIFT) & 3; 3750 int iopl = (flags >> IOPL_SHIFT) & 3; 3751 3752 dc->cs_base = dc->base.tb->cs_base; 3753 dc->pc_save = dc->base.pc_next; 3754 dc->flags = flags; 3755 #ifndef CONFIG_USER_ONLY 3756 dc->cpl = cpl; 3757 dc->iopl = iopl; 3758 #endif 3759 3760 /* We make some simplifying assumptions; validate they're correct. */ 3761 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); 3762 g_assert(CPL(dc) == cpl); 3763 g_assert(IOPL(dc) == iopl); 3764 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0)); 3765 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0)); 3766 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0)); 3767 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0)); 3768 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0)); 3769 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0)); 3770 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0)); 3771 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0)); 3772 3773 dc->cc_op = CC_OP_DYNAMIC; 3774 dc->cc_op_dirty = false; 3775 /* select memory access functions */ 3776 dc->mem_index = cpu_mmu_index(cpu, false); 3777 dc->cpuid_features = env->features[FEAT_1_EDX]; 3778 dc->cpuid_ext_features = env->features[FEAT_1_ECX]; 3779 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; 3780 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; 3781 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; 3782 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX]; 3783 dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX]; 3784 dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; 3785 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || 3786 (flags & (HF_RF_MASK | HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 3787 3788 dc->T0 = tcg_temp_new(); 3789 dc->T1 = tcg_temp_new(); 3790 dc->A0 = tcg_temp_new(); 3791 3792 dc->tmp1_i64 = tcg_temp_new_i64(); 3793 dc->tmp2_i32 = tcg_temp_new_i32(); 3794 dc->cc_srcT = tcg_temp_new(); 3795 } 3796 3797 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) 3798 { 3799 } 3800 3801 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 3802 { 3803 DisasContext *dc = container_of(dcbase, DisasContext, base); 3804 target_ulong pc_arg = dc->base.pc_next; 3805 3806 dc->prev_insn_start = dc->base.insn_start; 3807 dc->prev_insn_end = tcg_last_op(); 3808 if (tb_cflags(dcbase->tb) & CF_PCREL) { 3809 pc_arg &= ~TARGET_PAGE_MASK; 3810 } 3811 tcg_gen_insn_start(pc_arg, dc->cc_op); 3812 } 3813 3814 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 3815 { 3816 DisasContext *dc = container_of(dcbase, DisasContext, base); 3817 bool orig_cc_op_dirty = dc->cc_op_dirty; 3818 CCOp orig_cc_op = dc->cc_op; 3819 target_ulong orig_pc_save = dc->pc_save; 3820 3821 #ifdef TARGET_VSYSCALL_PAGE 3822 /* 3823 * Detect entry into the vsyscall page and invoke the syscall. 3824 */ 3825 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) { 3826 gen_exception(dc, EXCP_VSYSCALL); 3827 dc->base.pc_next = dc->pc + 1; 3828 return; 3829 } 3830 #endif 3831 3832 switch (sigsetjmp(dc->jmpbuf, 0)) { 3833 case 0: 3834 disas_insn(dc, cpu); 3835 break; 3836 case 1: 3837 gen_exception_gpf(dc); 3838 break; 3839 case 2: 3840 /* Restore state that may affect the next instruction. */ 3841 dc->pc = dc->base.pc_next; 3842 assert(dc->cc_op_dirty == orig_cc_op_dirty); 3843 assert(dc->cc_op == orig_cc_op); 3844 assert(dc->pc_save == orig_pc_save); 3845 dc->base.num_insns--; 3846 tcg_remove_ops_after(dc->prev_insn_end); 3847 dc->base.insn_start = dc->prev_insn_start; 3848 dc->base.is_jmp = DISAS_TOO_MANY; 3849 return; 3850 default: 3851 g_assert_not_reached(); 3852 } 3853 3854 /* 3855 * Instruction decoding completed (possibly with #GP if the 3856 * 15-byte boundary was exceeded). 3857 */ 3858 dc->base.pc_next = dc->pc; 3859 if (dc->base.is_jmp == DISAS_NEXT) { 3860 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) { 3861 /* 3862 * If single step mode, we generate only one instruction and 3863 * generate an exception. 3864 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 3865 * the flag and abort the translation to give the irqs a 3866 * chance to happen. 3867 */ 3868 dc->base.is_jmp = DISAS_EOB_NEXT; 3869 } else if (!translator_is_same_page(&dc->base, dc->base.pc_next)) { 3870 dc->base.is_jmp = DISAS_TOO_MANY; 3871 } 3872 } 3873 } 3874 3875 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 3876 { 3877 DisasContext *dc = container_of(dcbase, DisasContext, base); 3878 3879 switch (dc->base.is_jmp) { 3880 case DISAS_NORETURN: 3881 /* 3882 * Most instructions should not use DISAS_NORETURN, as that suppresses 3883 * the handling of hflags normally done by gen_eob(). We can 3884 * get here: 3885 * - for exception and interrupts 3886 * - for jump optimization (which is disabled by INHIBIT_IRQ/RF/TF) 3887 * - for VMRUN because RF/TF handling for the host is done after vmexit, 3888 * and INHIBIT_IRQ is loaded from the VMCB 3889 * - for HLT/PAUSE/MWAIT to exit the main loop with specific EXCP_* values; 3890 * the helpers handle themselves the tasks normally done by gen_eob(). 3891 */ 3892 break; 3893 case DISAS_TOO_MANY: 3894 gen_update_cc_op(dc); 3895 gen_jmp_rel_csize(dc, 0, 0); 3896 break; 3897 case DISAS_EOB_NEXT: 3898 case DISAS_EOB_INHIBIT_IRQ: 3899 assert(dc->base.pc_next == dc->pc); 3900 gen_update_eip_cur(dc); 3901 /* fall through */ 3902 case DISAS_EOB_ONLY: 3903 case DISAS_EOB_RECHECK_TF: 3904 case DISAS_JUMP: 3905 gen_eob(dc, dc->base.is_jmp); 3906 break; 3907 default: 3908 g_assert_not_reached(); 3909 } 3910 } 3911 3912 static const TranslatorOps i386_tr_ops = { 3913 .init_disas_context = i386_tr_init_disas_context, 3914 .tb_start = i386_tr_tb_start, 3915 .insn_start = i386_tr_insn_start, 3916 .translate_insn = i386_tr_translate_insn, 3917 .tb_stop = i386_tr_tb_stop, 3918 }; 3919 3920 void x86_translate_code(CPUState *cpu, TranslationBlock *tb, 3921 int *max_insns, vaddr pc, void *host_pc) 3922 { 3923 DisasContext dc; 3924 3925 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); 3926 } 3927