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