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