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