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