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