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 "tcg/tcg-op.h" 25 #include "tcg/tcg-op-gvec.h" 26 #include "exec/cpu_ldst.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 34 #include "exec/log.h" 35 36 #define HELPER_H "helper.h" 37 #include "exec/helper-info.c.inc" 38 #undef HELPER_H 39 40 /* Fixes for Windows namespace pollution. */ 41 #undef IN 42 #undef OUT 43 44 #define PREFIX_REPZ 0x01 45 #define PREFIX_REPNZ 0x02 46 #define PREFIX_LOCK 0x04 47 #define PREFIX_DATA 0x08 48 #define PREFIX_ADR 0x10 49 #define PREFIX_VEX 0x20 50 #define PREFIX_REX 0x40 51 52 #ifdef TARGET_X86_64 53 # define ctztl ctz64 54 # define clztl clz64 55 #else 56 # define ctztl ctz32 57 # define clztl clz32 58 #endif 59 60 /* For a switch indexed by MODRM, match all memory operands for a given OP. */ 61 #define CASE_MODRM_MEM_OP(OP) \ 62 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 63 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 64 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7 65 66 #define CASE_MODRM_OP(OP) \ 67 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 68 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 69 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \ 70 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7 71 72 //#define MACRO_TEST 1 73 74 /* global register indexes */ 75 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2; 76 static TCGv cpu_eip; 77 static TCGv_i32 cpu_cc_op; 78 static TCGv cpu_regs[CPU_NB_REGS]; 79 static TCGv cpu_seg_base[6]; 80 static TCGv_i64 cpu_bndl[4]; 81 static TCGv_i64 cpu_bndu[4]; 82 83 typedef struct DisasContext { 84 DisasContextBase base; 85 86 target_ulong pc; /* pc = eip + cs_base */ 87 target_ulong cs_base; /* base of CS segment */ 88 target_ulong pc_save; 89 90 MemOp aflag; 91 MemOp dflag; 92 93 int8_t override; /* -1 if no override, else R_CS, R_DS, etc */ 94 uint8_t prefix; 95 96 bool has_modrm; 97 uint8_t modrm; 98 99 #ifndef CONFIG_USER_ONLY 100 uint8_t cpl; /* code priv level */ 101 uint8_t iopl; /* i/o priv level */ 102 #endif 103 uint8_t vex_l; /* vex vector length */ 104 uint8_t vex_v; /* vex vvvv register, without 1's complement. */ 105 uint8_t popl_esp_hack; /* for correct popl with esp base handling */ 106 uint8_t rip_offset; /* only used in x86_64, but left for simplicity */ 107 108 #ifdef TARGET_X86_64 109 uint8_t rex_r; 110 uint8_t rex_x; 111 uint8_t rex_b; 112 #endif 113 bool vex_w; /* used by AVX even on 32-bit processors */ 114 bool jmp_opt; /* use direct block chaining for direct jumps */ 115 bool repz_opt; /* optimize jumps within repz instructions */ 116 bool cc_op_dirty; 117 118 CCOp cc_op; /* current CC operation */ 119 int mem_index; /* select memory access functions */ 120 uint32_t flags; /* all execution flags */ 121 int cpuid_features; 122 int cpuid_ext_features; 123 int cpuid_ext2_features; 124 int cpuid_ext3_features; 125 int cpuid_7_0_ebx_features; 126 int cpuid_7_0_ecx_features; 127 int cpuid_7_1_eax_features; 128 int cpuid_xsave_features; 129 130 /* TCG local temps */ 131 TCGv cc_srcT; 132 TCGv A0; 133 TCGv T0; 134 TCGv T1; 135 136 /* TCG local register indexes (only used inside old micro ops) */ 137 TCGv tmp0; 138 TCGv tmp4; 139 TCGv_i32 tmp2_i32; 140 TCGv_i32 tmp3_i32; 141 TCGv_i64 tmp1_i64; 142 143 sigjmp_buf jmpbuf; 144 TCGOp *prev_insn_start; 145 TCGOp *prev_insn_end; 146 } DisasContext; 147 148 #define DISAS_EOB_ONLY DISAS_TARGET_0 149 #define DISAS_EOB_NEXT DISAS_TARGET_1 150 #define DISAS_EOB_INHIBIT_IRQ DISAS_TARGET_2 151 #define DISAS_JUMP DISAS_TARGET_3 152 153 /* The environment in which user-only runs is constrained. */ 154 #ifdef CONFIG_USER_ONLY 155 #define PE(S) true 156 #define CPL(S) 3 157 #define IOPL(S) 0 158 #define SVME(S) false 159 #define GUEST(S) false 160 #else 161 #define PE(S) (((S)->flags & HF_PE_MASK) != 0) 162 #define CPL(S) ((S)->cpl) 163 #define IOPL(S) ((S)->iopl) 164 #define SVME(S) (((S)->flags & HF_SVME_MASK) != 0) 165 #define GUEST(S) (((S)->flags & HF_GUEST_MASK) != 0) 166 #endif 167 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64) 168 #define VM86(S) false 169 #define CODE32(S) true 170 #define SS32(S) true 171 #define ADDSEG(S) false 172 #else 173 #define VM86(S) (((S)->flags & HF_VM_MASK) != 0) 174 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0) 175 #define SS32(S) (((S)->flags & HF_SS32_MASK) != 0) 176 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0) 177 #endif 178 #if !defined(TARGET_X86_64) 179 #define CODE64(S) false 180 #elif defined(CONFIG_USER_ONLY) 181 #define CODE64(S) true 182 #else 183 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0) 184 #endif 185 #if defined(CONFIG_USER_ONLY) || defined(TARGET_X86_64) 186 #define LMA(S) (((S)->flags & HF_LMA_MASK) != 0) 187 #else 188 #define LMA(S) false 189 #endif 190 191 #ifdef TARGET_X86_64 192 #define REX_PREFIX(S) (((S)->prefix & PREFIX_REX) != 0) 193 #define REX_W(S) ((S)->vex_w) 194 #define REX_R(S) ((S)->rex_r + 0) 195 #define REX_X(S) ((S)->rex_x + 0) 196 #define REX_B(S) ((S)->rex_b + 0) 197 #else 198 #define REX_PREFIX(S) false 199 #define REX_W(S) false 200 #define REX_R(S) 0 201 #define REX_X(S) 0 202 #define REX_B(S) 0 203 #endif 204 205 /* 206 * Many sysemu-only helpers are not reachable for user-only. 207 * Define stub generators here, so that we need not either sprinkle 208 * ifdefs through the translator, nor provide the helper function. 209 */ 210 #define STUB_HELPER(NAME, ...) \ 211 static inline void gen_helper_##NAME(__VA_ARGS__) \ 212 { qemu_build_not_reached(); } 213 214 #ifdef CONFIG_USER_ONLY 215 STUB_HELPER(clgi, TCGv_env env) 216 STUB_HELPER(flush_page, TCGv_env env, TCGv addr) 217 STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port) 218 STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port) 219 STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port) 220 STUB_HELPER(monitor, TCGv_env env, TCGv addr) 221 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs) 222 STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 223 STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 224 STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 225 STUB_HELPER(rdmsr, TCGv_env env) 226 STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg) 227 STUB_HELPER(get_dr, TCGv ret, TCGv_env env, TCGv_i32 reg) 228 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val) 229 STUB_HELPER(stgi, TCGv_env env) 230 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type) 231 STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag) 232 STUB_HELPER(vmmcall, TCGv_env env) 233 STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs) 234 STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag) 235 STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val) 236 STUB_HELPER(wrmsr, TCGv_env env) 237 #endif 238 239 static void gen_eob(DisasContext *s); 240 static void gen_jr(DisasContext *s); 241 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num); 242 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num); 243 static void gen_exception_gpf(DisasContext *s); 244 245 /* i386 shift ops */ 246 enum { 247 OP_ROL, 248 OP_ROR, 249 OP_RCL, 250 OP_RCR, 251 OP_SHL, 252 OP_SHR, 253 OP_SHL1, /* undocumented */ 254 OP_SAR = 7, 255 }; 256 257 enum { 258 JCC_O, 259 JCC_B, 260 JCC_Z, 261 JCC_BE, 262 JCC_S, 263 JCC_P, 264 JCC_L, 265 JCC_LE, 266 }; 267 268 enum { 269 /* I386 int registers */ 270 OR_EAX, /* MUST be even numbered */ 271 OR_ECX, 272 OR_EDX, 273 OR_EBX, 274 OR_ESP, 275 OR_EBP, 276 OR_ESI, 277 OR_EDI, 278 279 OR_TMP0 = 16, /* temporary operand register */ 280 OR_TMP1, 281 OR_A0, /* temporary register used when doing address evaluation */ 282 }; 283 284 enum { 285 USES_CC_DST = 1, 286 USES_CC_SRC = 2, 287 USES_CC_SRC2 = 4, 288 USES_CC_SRCT = 8, 289 }; 290 291 /* Bit set if the global variable is live after setting CC_OP to X. */ 292 static const uint8_t cc_op_live[CC_OP_NB] = { 293 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 294 [CC_OP_EFLAGS] = USES_CC_SRC, 295 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC, 296 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC, 297 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 298 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT, 299 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 300 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST, 301 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC, 302 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC, 303 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC, 304 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC, 305 [CC_OP_BMILGB ... CC_OP_BMILGQ] = 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_CLR] = 0, 310 [CC_OP_POPCNT] = USES_CC_SRC, 311 }; 312 313 static void set_cc_op(DisasContext *s, CCOp op) 314 { 315 int dead; 316 317 if (s->cc_op == op) { 318 return; 319 } 320 321 /* Discard CC computation that will no longer be used. */ 322 dead = cc_op_live[s->cc_op] & ~cc_op_live[op]; 323 if (dead & USES_CC_DST) { 324 tcg_gen_discard_tl(cpu_cc_dst); 325 } 326 if (dead & USES_CC_SRC) { 327 tcg_gen_discard_tl(cpu_cc_src); 328 } 329 if (dead & USES_CC_SRC2) { 330 tcg_gen_discard_tl(cpu_cc_src2); 331 } 332 if (dead & USES_CC_SRCT) { 333 tcg_gen_discard_tl(s->cc_srcT); 334 } 335 336 if (op == CC_OP_DYNAMIC) { 337 /* The DYNAMIC setting is translator only, and should never be 338 stored. Thus we always consider it clean. */ 339 s->cc_op_dirty = false; 340 } else { 341 /* Discard any computed CC_OP value (see shifts). */ 342 if (s->cc_op == CC_OP_DYNAMIC) { 343 tcg_gen_discard_i32(cpu_cc_op); 344 } 345 s->cc_op_dirty = true; 346 } 347 s->cc_op = op; 348 } 349 350 static void gen_update_cc_op(DisasContext *s) 351 { 352 if (s->cc_op_dirty) { 353 tcg_gen_movi_i32(cpu_cc_op, s->cc_op); 354 s->cc_op_dirty = false; 355 } 356 } 357 358 #ifdef TARGET_X86_64 359 360 #define NB_OP_SIZES 4 361 362 #else /* !TARGET_X86_64 */ 363 364 #define NB_OP_SIZES 3 365 366 #endif /* !TARGET_X86_64 */ 367 368 #if HOST_BIG_ENDIAN 369 #define REG_B_OFFSET (sizeof(target_ulong) - 1) 370 #define REG_H_OFFSET (sizeof(target_ulong) - 2) 371 #define REG_W_OFFSET (sizeof(target_ulong) - 2) 372 #define REG_L_OFFSET (sizeof(target_ulong) - 4) 373 #define REG_LH_OFFSET (sizeof(target_ulong) - 8) 374 #else 375 #define REG_B_OFFSET 0 376 #define REG_H_OFFSET 1 377 #define REG_W_OFFSET 0 378 #define REG_L_OFFSET 0 379 #define REG_LH_OFFSET 4 380 #endif 381 382 /* In instruction encodings for byte register accesses the 383 * register number usually indicates "low 8 bits of register N"; 384 * however there are some special cases where N 4..7 indicates 385 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return 386 * true for this special case, false otherwise. 387 */ 388 static inline bool byte_reg_is_xH(DisasContext *s, int reg) 389 { 390 /* Any time the REX prefix is present, byte registers are uniform */ 391 if (reg < 4 || REX_PREFIX(s)) { 392 return false; 393 } 394 return true; 395 } 396 397 /* Select the size of a push/pop operation. */ 398 static inline MemOp mo_pushpop(DisasContext *s, MemOp ot) 399 { 400 if (CODE64(s)) { 401 return ot == MO_16 ? MO_16 : MO_64; 402 } else { 403 return ot; 404 } 405 } 406 407 /* Select the size of the stack pointer. */ 408 static inline MemOp mo_stacksize(DisasContext *s) 409 { 410 return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16; 411 } 412 413 /* Select size 8 if lsb of B is clear, else OT. Used for decoding 414 byte vs word opcodes. */ 415 static inline MemOp mo_b_d(int b, MemOp ot) 416 { 417 return b & 1 ? ot : MO_8; 418 } 419 420 /* Compute the result of writing t0 to the OT-sized register REG. 421 * 422 * If DEST is NULL, store the result into the register and return the 423 * register's TCGv. 424 * 425 * If DEST is not NULL, store the result into DEST and return the 426 * register's TCGv. 427 */ 428 static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest, TCGv t0) 429 { 430 switch(ot) { 431 case MO_8: 432 if (byte_reg_is_xH(s, reg)) { 433 dest = dest ? dest : cpu_regs[reg - 4]; 434 tcg_gen_deposit_tl(dest, cpu_regs[reg - 4], t0, 8, 8); 435 return cpu_regs[reg - 4]; 436 } 437 dest = dest ? dest : cpu_regs[reg]; 438 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 8); 439 break; 440 case MO_16: 441 dest = dest ? dest : cpu_regs[reg]; 442 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 16); 443 break; 444 case MO_32: 445 /* For x86_64, this sets the higher half of register to zero. 446 For i386, this is equivalent to a mov. */ 447 dest = dest ? dest : cpu_regs[reg]; 448 tcg_gen_ext32u_tl(dest, t0); 449 break; 450 #ifdef TARGET_X86_64 451 case MO_64: 452 dest = dest ? dest : cpu_regs[reg]; 453 tcg_gen_mov_tl(dest, t0); 454 break; 455 #endif 456 default: 457 g_assert_not_reached(); 458 } 459 return cpu_regs[reg]; 460 } 461 462 static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0) 463 { 464 gen_op_deposit_reg_v(s, ot, reg, NULL, t0); 465 } 466 467 static inline 468 void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg) 469 { 470 if (ot == MO_8 && byte_reg_is_xH(s, reg)) { 471 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8); 472 } else { 473 tcg_gen_mov_tl(t0, cpu_regs[reg]); 474 } 475 } 476 477 static void gen_add_A0_im(DisasContext *s, int val) 478 { 479 tcg_gen_addi_tl(s->A0, s->A0, val); 480 if (!CODE64(s)) { 481 tcg_gen_ext32u_tl(s->A0, s->A0); 482 } 483 } 484 485 static inline void gen_op_jmp_v(DisasContext *s, TCGv dest) 486 { 487 tcg_gen_mov_tl(cpu_eip, dest); 488 s->pc_save = -1; 489 } 490 491 static inline 492 void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val) 493 { 494 tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val); 495 gen_op_mov_reg_v(s, size, reg, s->tmp0); 496 } 497 498 static inline void gen_op_add_reg(DisasContext *s, MemOp size, int reg, TCGv val) 499 { 500 tcg_gen_add_tl(s->tmp0, cpu_regs[reg], val); 501 gen_op_mov_reg_v(s, size, reg, s->tmp0); 502 } 503 504 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 505 { 506 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE); 507 } 508 509 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 510 { 511 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE); 512 } 513 514 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d) 515 { 516 if (d == OR_TMP0) { 517 gen_op_st_v(s, idx, s->T0, s->A0); 518 } else { 519 gen_op_mov_reg_v(s, idx, d, s->T0); 520 } 521 } 522 523 static void gen_update_eip_cur(DisasContext *s) 524 { 525 assert(s->pc_save != -1); 526 if (tb_cflags(s->base.tb) & CF_PCREL) { 527 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save); 528 } else if (CODE64(s)) { 529 tcg_gen_movi_tl(cpu_eip, s->base.pc_next); 530 } else { 531 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->base.pc_next - s->cs_base)); 532 } 533 s->pc_save = s->base.pc_next; 534 } 535 536 static void gen_update_eip_next(DisasContext *s) 537 { 538 assert(s->pc_save != -1); 539 if (tb_cflags(s->base.tb) & CF_PCREL) { 540 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save); 541 } else if (CODE64(s)) { 542 tcg_gen_movi_tl(cpu_eip, s->pc); 543 } else { 544 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->pc - s->cs_base)); 545 } 546 s->pc_save = s->pc; 547 } 548 549 static int cur_insn_len(DisasContext *s) 550 { 551 return s->pc - s->base.pc_next; 552 } 553 554 static TCGv_i32 cur_insn_len_i32(DisasContext *s) 555 { 556 return tcg_constant_i32(cur_insn_len(s)); 557 } 558 559 static TCGv_i32 eip_next_i32(DisasContext *s) 560 { 561 assert(s->pc_save != -1); 562 /* 563 * This function has two users: lcall_real (always 16-bit mode), and 564 * iret_protected (16, 32, or 64-bit mode). IRET only uses the value 565 * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is 566 * why passing a 32-bit value isn't broken. To avoid using this where 567 * we shouldn't, return -1 in 64-bit mode so that execution goes into 568 * the weeds quickly. 569 */ 570 if (CODE64(s)) { 571 return tcg_constant_i32(-1); 572 } 573 if (tb_cflags(s->base.tb) & CF_PCREL) { 574 TCGv_i32 ret = tcg_temp_new_i32(); 575 tcg_gen_trunc_tl_i32(ret, cpu_eip); 576 tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save); 577 return ret; 578 } else { 579 return tcg_constant_i32(s->pc - s->cs_base); 580 } 581 } 582 583 static TCGv eip_next_tl(DisasContext *s) 584 { 585 assert(s->pc_save != -1); 586 if (tb_cflags(s->base.tb) & CF_PCREL) { 587 TCGv ret = tcg_temp_new(); 588 tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save); 589 return ret; 590 } else if (CODE64(s)) { 591 return tcg_constant_tl(s->pc); 592 } else { 593 return tcg_constant_tl((uint32_t)(s->pc - s->cs_base)); 594 } 595 } 596 597 static TCGv eip_cur_tl(DisasContext *s) 598 { 599 assert(s->pc_save != -1); 600 if (tb_cflags(s->base.tb) & CF_PCREL) { 601 TCGv ret = tcg_temp_new(); 602 tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save); 603 return ret; 604 } else if (CODE64(s)) { 605 return tcg_constant_tl(s->base.pc_next); 606 } else { 607 return tcg_constant_tl((uint32_t)(s->base.pc_next - s->cs_base)); 608 } 609 } 610 611 /* Compute SEG:REG into DEST. SEG is selected from the override segment 612 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to 613 indicate no override. */ 614 static void gen_lea_v_seg_dest(DisasContext *s, MemOp aflag, TCGv dest, TCGv a0, 615 int def_seg, int ovr_seg) 616 { 617 switch (aflag) { 618 #ifdef TARGET_X86_64 619 case MO_64: 620 if (ovr_seg < 0) { 621 tcg_gen_mov_tl(dest, a0); 622 return; 623 } 624 break; 625 #endif 626 case MO_32: 627 /* 32 bit address */ 628 if (ovr_seg < 0 && ADDSEG(s)) { 629 ovr_seg = def_seg; 630 } 631 if (ovr_seg < 0) { 632 tcg_gen_ext32u_tl(dest, a0); 633 return; 634 } 635 break; 636 case MO_16: 637 /* 16 bit address */ 638 tcg_gen_ext16u_tl(dest, a0); 639 a0 = dest; 640 if (ovr_seg < 0) { 641 if (ADDSEG(s)) { 642 ovr_seg = def_seg; 643 } else { 644 return; 645 } 646 } 647 break; 648 default: 649 g_assert_not_reached(); 650 } 651 652 if (ovr_seg >= 0) { 653 TCGv seg = cpu_seg_base[ovr_seg]; 654 655 if (aflag == MO_64) { 656 tcg_gen_add_tl(dest, a0, seg); 657 } else if (CODE64(s)) { 658 tcg_gen_ext32u_tl(dest, a0); 659 tcg_gen_add_tl(dest, dest, seg); 660 } else { 661 tcg_gen_add_tl(dest, a0, seg); 662 tcg_gen_ext32u_tl(dest, dest); 663 } 664 } 665 } 666 667 static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0, 668 int def_seg, int ovr_seg) 669 { 670 gen_lea_v_seg_dest(s, aflag, s->A0, a0, def_seg, ovr_seg); 671 } 672 673 static inline void gen_string_movl_A0_ESI(DisasContext *s) 674 { 675 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override); 676 } 677 678 static inline void gen_string_movl_A0_EDI(DisasContext *s) 679 { 680 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1); 681 } 682 683 static inline TCGv gen_compute_Dshift(DisasContext *s, MemOp ot) 684 { 685 TCGv dshift = tcg_temp_new(); 686 tcg_gen_ld32s_tl(dshift, tcg_env, offsetof(CPUX86State, df)); 687 tcg_gen_shli_tl(dshift, dshift, ot); 688 return dshift; 689 }; 690 691 static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign) 692 { 693 if (size == MO_TL) { 694 return src; 695 } 696 if (!dst) { 697 dst = tcg_temp_new(); 698 } 699 tcg_gen_ext_tl(dst, src, size | (sign ? MO_SIGN : 0)); 700 return dst; 701 } 702 703 static void gen_extu(MemOp ot, TCGv reg) 704 { 705 gen_ext_tl(reg, reg, ot, false); 706 } 707 708 static void gen_exts(MemOp ot, TCGv reg) 709 { 710 gen_ext_tl(reg, reg, ot, true); 711 } 712 713 static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1) 714 { 715 TCGv tmp = gen_ext_tl(NULL, cpu_regs[R_ECX], s->aflag, false); 716 717 tcg_gen_brcondi_tl(cond, tmp, 0, label1); 718 } 719 720 static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1) 721 { 722 gen_op_j_ecx(s, TCG_COND_EQ, label1); 723 } 724 725 static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1) 726 { 727 gen_op_j_ecx(s, TCG_COND_NE, label1); 728 } 729 730 static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n) 731 { 732 switch (ot) { 733 case MO_8: 734 gen_helper_inb(v, tcg_env, n); 735 break; 736 case MO_16: 737 gen_helper_inw(v, tcg_env, n); 738 break; 739 case MO_32: 740 gen_helper_inl(v, tcg_env, n); 741 break; 742 default: 743 g_assert_not_reached(); 744 } 745 } 746 747 static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n) 748 { 749 switch (ot) { 750 case MO_8: 751 gen_helper_outb(tcg_env, v, n); 752 break; 753 case MO_16: 754 gen_helper_outw(tcg_env, v, n); 755 break; 756 case MO_32: 757 gen_helper_outl(tcg_env, v, n); 758 break; 759 default: 760 g_assert_not_reached(); 761 } 762 } 763 764 /* 765 * Validate that access to [port, port + 1<<ot) is allowed. 766 * Raise #GP, or VMM exit if not. 767 */ 768 static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port, 769 uint32_t svm_flags) 770 { 771 #ifdef CONFIG_USER_ONLY 772 /* 773 * We do not implement the ioperm(2) syscall, so the TSS check 774 * will always fail. 775 */ 776 gen_exception_gpf(s); 777 return false; 778 #else 779 if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) { 780 gen_helper_check_io(tcg_env, port, tcg_constant_i32(1 << ot)); 781 } 782 if (GUEST(s)) { 783 gen_update_cc_op(s); 784 gen_update_eip_cur(s); 785 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) { 786 svm_flags |= SVM_IOIO_REP_MASK; 787 } 788 svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot); 789 gen_helper_svm_check_io(tcg_env, port, 790 tcg_constant_i32(svm_flags), 791 cur_insn_len_i32(s)); 792 } 793 return true; 794 #endif 795 } 796 797 static void gen_movs(DisasContext *s, MemOp ot) 798 { 799 TCGv dshift; 800 801 gen_string_movl_A0_ESI(s); 802 gen_op_ld_v(s, ot, s->T0, s->A0); 803 gen_string_movl_A0_EDI(s); 804 gen_op_st_v(s, ot, s->T0, s->A0); 805 806 dshift = gen_compute_Dshift(s, ot); 807 gen_op_add_reg(s, s->aflag, R_ESI, dshift); 808 gen_op_add_reg(s, s->aflag, R_EDI, dshift); 809 } 810 811 static void gen_op_update1_cc(DisasContext *s) 812 { 813 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 814 } 815 816 static void gen_op_update2_cc(DisasContext *s) 817 { 818 tcg_gen_mov_tl(cpu_cc_src, s->T1); 819 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 820 } 821 822 /* compute all eflags to reg */ 823 static void gen_mov_eflags(DisasContext *s, TCGv reg) 824 { 825 TCGv dst, src1, src2; 826 TCGv_i32 cc_op; 827 int live, dead; 828 829 if (s->cc_op == CC_OP_EFLAGS) { 830 tcg_gen_mov_tl(reg, cpu_cc_src); 831 return; 832 } 833 if (s->cc_op == CC_OP_CLR) { 834 tcg_gen_movi_tl(reg, CC_Z | CC_P); 835 return; 836 } 837 838 dst = cpu_cc_dst; 839 src1 = cpu_cc_src; 840 src2 = cpu_cc_src2; 841 842 /* Take care to not read values that are not live. */ 843 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT; 844 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2); 845 if (dead) { 846 TCGv zero = tcg_constant_tl(0); 847 if (dead & USES_CC_DST) { 848 dst = zero; 849 } 850 if (dead & USES_CC_SRC) { 851 src1 = zero; 852 } 853 if (dead & USES_CC_SRC2) { 854 src2 = zero; 855 } 856 } 857 858 if (s->cc_op != CC_OP_DYNAMIC) { 859 cc_op = tcg_constant_i32(s->cc_op); 860 } else { 861 cc_op = cpu_cc_op; 862 } 863 gen_helper_cc_compute_all(reg, dst, src1, src2, cc_op); 864 } 865 866 /* compute all eflags to cc_src */ 867 static void gen_compute_eflags(DisasContext *s) 868 { 869 gen_mov_eflags(s, cpu_cc_src); 870 set_cc_op(s, CC_OP_EFLAGS); 871 } 872 873 typedef struct CCPrepare { 874 TCGCond cond; 875 TCGv reg; 876 TCGv reg2; 877 target_ulong imm; 878 bool use_reg2; 879 bool no_setcond; 880 } CCPrepare; 881 882 static CCPrepare gen_prepare_sign_nz(TCGv src, MemOp size) 883 { 884 if (size == MO_TL) { 885 return (CCPrepare) { .cond = TCG_COND_LT, .reg = src }; 886 } else { 887 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = src, 888 .imm = 1ull << ((8 << size) - 1) }; 889 } 890 } 891 892 /* compute eflags.C, trying to store it in reg if not NULL */ 893 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg) 894 { 895 MemOp size; 896 897 switch (s->cc_op) { 898 case CC_OP_SUBB ... CC_OP_SUBQ: 899 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */ 900 size = s->cc_op - CC_OP_SUBB; 901 gen_ext_tl(s->cc_srcT, s->cc_srcT, size, false); 902 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 903 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = s->cc_srcT, 904 .reg2 = cpu_cc_src, .use_reg2 = true }; 905 906 case CC_OP_ADDB ... CC_OP_ADDQ: 907 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */ 908 size = s->cc_op - CC_OP_ADDB; 909 gen_ext_tl(cpu_cc_dst, cpu_cc_dst, size, false); 910 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 911 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = cpu_cc_dst, 912 .reg2 = cpu_cc_src, .use_reg2 = true }; 913 914 case CC_OP_LOGICB ... CC_OP_LOGICQ: 915 case CC_OP_CLR: 916 case CC_OP_POPCNT: 917 return (CCPrepare) { .cond = TCG_COND_NEVER }; 918 919 case CC_OP_INCB ... CC_OP_INCQ: 920 case CC_OP_DECB ... CC_OP_DECQ: 921 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 922 .no_setcond = true }; 923 924 case CC_OP_SHLB ... CC_OP_SHLQ: 925 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */ 926 size = s->cc_op - CC_OP_SHLB; 927 return gen_prepare_sign_nz(cpu_cc_src, size); 928 929 case CC_OP_MULB ... CC_OP_MULQ: 930 return (CCPrepare) { .cond = TCG_COND_NE, 931 .reg = cpu_cc_src }; 932 933 case CC_OP_BMILGB ... CC_OP_BMILGQ: 934 size = s->cc_op - CC_OP_BMILGB; 935 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 936 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src }; 937 938 case CC_OP_ADCX: 939 case CC_OP_ADCOX: 940 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst, 941 .no_setcond = true }; 942 943 case CC_OP_EFLAGS: 944 case CC_OP_SARB ... CC_OP_SARQ: 945 /* CC_SRC & 1 */ 946 return (CCPrepare) { .cond = TCG_COND_TSTNE, 947 .reg = cpu_cc_src, .imm = CC_C }; 948 949 default: 950 /* The need to compute only C from CC_OP_DYNAMIC is important 951 in efficiently implementing e.g. INC at the start of a TB. */ 952 gen_update_cc_op(s); 953 if (!reg) { 954 reg = tcg_temp_new(); 955 } 956 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src, 957 cpu_cc_src2, cpu_cc_op); 958 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg, 959 .no_setcond = true }; 960 } 961 } 962 963 /* compute eflags.P, trying to store it in reg if not NULL */ 964 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg) 965 { 966 gen_compute_eflags(s); 967 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 968 .imm = CC_P }; 969 } 970 971 /* compute eflags.S, trying to store it in reg if not NULL */ 972 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg) 973 { 974 switch (s->cc_op) { 975 case CC_OP_DYNAMIC: 976 gen_compute_eflags(s); 977 /* FALLTHRU */ 978 case CC_OP_EFLAGS: 979 case CC_OP_ADCX: 980 case CC_OP_ADOX: 981 case CC_OP_ADCOX: 982 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 983 .imm = CC_S }; 984 case CC_OP_CLR: 985 case CC_OP_POPCNT: 986 return (CCPrepare) { .cond = TCG_COND_NEVER }; 987 default: 988 { 989 MemOp size = (s->cc_op - CC_OP_ADDB) & 3; 990 return gen_prepare_sign_nz(cpu_cc_dst, size); 991 } 992 } 993 } 994 995 /* compute eflags.O, trying to store it in reg if not NULL */ 996 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg) 997 { 998 switch (s->cc_op) { 999 case CC_OP_ADOX: 1000 case CC_OP_ADCOX: 1001 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2, 1002 .no_setcond = true }; 1003 case CC_OP_CLR: 1004 case CC_OP_POPCNT: 1005 return (CCPrepare) { .cond = TCG_COND_NEVER }; 1006 case CC_OP_MULB ... CC_OP_MULQ: 1007 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src }; 1008 default: 1009 gen_compute_eflags(s); 1010 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1011 .imm = CC_O }; 1012 } 1013 } 1014 1015 /* compute eflags.Z, trying to store it in reg if not NULL */ 1016 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg) 1017 { 1018 switch (s->cc_op) { 1019 case CC_OP_DYNAMIC: 1020 gen_compute_eflags(s); 1021 /* FALLTHRU */ 1022 case CC_OP_EFLAGS: 1023 case CC_OP_ADCX: 1024 case CC_OP_ADOX: 1025 case CC_OP_ADCOX: 1026 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1027 .imm = CC_Z }; 1028 case CC_OP_CLR: 1029 return (CCPrepare) { .cond = TCG_COND_ALWAYS }; 1030 case CC_OP_POPCNT: 1031 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src }; 1032 default: 1033 { 1034 MemOp size = (s->cc_op - CC_OP_ADDB) & 3; 1035 if (size == MO_TL) { 1036 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_dst }; 1037 } else { 1038 return (CCPrepare) { .cond = TCG_COND_TSTEQ, .reg = cpu_cc_dst, 1039 .imm = (1ull << (8 << size)) - 1 }; 1040 } 1041 } 1042 } 1043 } 1044 1045 /* return how to compute jump opcode 'b'. 'reg' can be clobbered 1046 * if needed; it may be used for CCPrepare.reg if that will 1047 * provide more freedom in the translation of a subsequent setcond. */ 1048 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg) 1049 { 1050 int inv, jcc_op, cond; 1051 MemOp size; 1052 CCPrepare cc; 1053 1054 inv = b & 1; 1055 jcc_op = (b >> 1) & 7; 1056 1057 switch (s->cc_op) { 1058 case CC_OP_SUBB ... CC_OP_SUBQ: 1059 /* We optimize relational operators for the cmp/jcc case. */ 1060 size = s->cc_op - CC_OP_SUBB; 1061 switch (jcc_op) { 1062 case JCC_BE: 1063 gen_ext_tl(s->cc_srcT, s->cc_srcT, size, false); 1064 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 1065 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->cc_srcT, 1066 .reg2 = cpu_cc_src, .use_reg2 = true }; 1067 break; 1068 case JCC_L: 1069 cond = TCG_COND_LT; 1070 goto fast_jcc_l; 1071 case JCC_LE: 1072 cond = TCG_COND_LE; 1073 fast_jcc_l: 1074 gen_ext_tl(s->cc_srcT, s->cc_srcT, size, true); 1075 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, true); 1076 cc = (CCPrepare) { .cond = cond, .reg = s->cc_srcT, 1077 .reg2 = cpu_cc_src, .use_reg2 = true }; 1078 break; 1079 1080 default: 1081 goto slow_jcc; 1082 } 1083 break; 1084 1085 default: 1086 slow_jcc: 1087 /* This actually generates good code for JC, JZ and JS. */ 1088 switch (jcc_op) { 1089 case JCC_O: 1090 cc = gen_prepare_eflags_o(s, reg); 1091 break; 1092 case JCC_B: 1093 cc = gen_prepare_eflags_c(s, reg); 1094 break; 1095 case JCC_Z: 1096 cc = gen_prepare_eflags_z(s, reg); 1097 break; 1098 case JCC_BE: 1099 gen_compute_eflags(s); 1100 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1101 .imm = CC_Z | CC_C }; 1102 break; 1103 case JCC_S: 1104 cc = gen_prepare_eflags_s(s, reg); 1105 break; 1106 case JCC_P: 1107 cc = gen_prepare_eflags_p(s, reg); 1108 break; 1109 case JCC_L: 1110 gen_compute_eflags(s); 1111 if (!reg || reg == cpu_cc_src) { 1112 reg = tcg_temp_new(); 1113 } 1114 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S); 1115 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg, 1116 .imm = CC_O }; 1117 break; 1118 default: 1119 case JCC_LE: 1120 gen_compute_eflags(s); 1121 if (!reg || reg == cpu_cc_src) { 1122 reg = tcg_temp_new(); 1123 } 1124 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S); 1125 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg, 1126 .imm = CC_O | CC_Z }; 1127 break; 1128 } 1129 break; 1130 } 1131 1132 if (inv) { 1133 cc.cond = tcg_invert_cond(cc.cond); 1134 } 1135 return cc; 1136 } 1137 1138 static void gen_setcc1(DisasContext *s, int b, TCGv reg) 1139 { 1140 CCPrepare cc = gen_prepare_cc(s, b, reg); 1141 1142 if (cc.no_setcond) { 1143 if (cc.cond == TCG_COND_EQ) { 1144 tcg_gen_xori_tl(reg, cc.reg, 1); 1145 } else { 1146 tcg_gen_mov_tl(reg, cc.reg); 1147 } 1148 return; 1149 } 1150 1151 if (cc.use_reg2) { 1152 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2); 1153 } else { 1154 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm); 1155 } 1156 } 1157 1158 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg) 1159 { 1160 gen_setcc1(s, JCC_B << 1, reg); 1161 } 1162 1163 /* generate a conditional jump to label 'l1' according to jump opcode 1164 value 'b'. In the fast case, T0 is guaranteed not to be used. */ 1165 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1) 1166 { 1167 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1168 1169 if (cc.use_reg2) { 1170 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1171 } else { 1172 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1173 } 1174 } 1175 1176 /* Generate a conditional jump to label 'l1' according to jump opcode 1177 value 'b'. In the fast case, T0 is guaranteed not to be used. 1178 One or both of the branches will call gen_jmp_rel, so ensure 1179 cc_op is clean. */ 1180 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1) 1181 { 1182 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1183 1184 gen_update_cc_op(s); 1185 if (cc.use_reg2) { 1186 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1187 } else { 1188 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1189 } 1190 } 1191 1192 /* XXX: does not work with gdbstub "ice" single step - not a 1193 serious problem. The caller can jump to the returned label 1194 to stop the REP but, if the flags have changed, it has to call 1195 gen_update_cc_op before doing so. */ 1196 static TCGLabel *gen_jz_ecx_string(DisasContext *s) 1197 { 1198 TCGLabel *l1 = gen_new_label(); 1199 TCGLabel *l2 = gen_new_label(); 1200 1201 gen_update_cc_op(s); 1202 gen_op_jnz_ecx(s, l1); 1203 gen_set_label(l2); 1204 gen_jmp_rel_csize(s, 0, 1); 1205 gen_set_label(l1); 1206 return l2; 1207 } 1208 1209 static void gen_stos(DisasContext *s, MemOp ot) 1210 { 1211 gen_string_movl_A0_EDI(s); 1212 gen_op_st_v(s, ot, s->T0, s->A0); 1213 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot)); 1214 } 1215 1216 static void gen_lods(DisasContext *s, MemOp ot) 1217 { 1218 gen_string_movl_A0_ESI(s); 1219 gen_op_ld_v(s, ot, s->T0, s->A0); 1220 gen_op_mov_reg_v(s, ot, R_EAX, s->T0); 1221 gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot)); 1222 } 1223 1224 static void gen_scas(DisasContext *s, MemOp ot) 1225 { 1226 gen_string_movl_A0_EDI(s); 1227 gen_op_ld_v(s, ot, s->T1, s->A0); 1228 tcg_gen_mov_tl(cpu_cc_src, s->T1); 1229 tcg_gen_mov_tl(s->cc_srcT, s->T0); 1230 tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1); 1231 set_cc_op(s, CC_OP_SUBB + ot); 1232 1233 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot)); 1234 } 1235 1236 static void gen_cmps(DisasContext *s, MemOp ot) 1237 { 1238 TCGv dshift; 1239 1240 gen_string_movl_A0_EDI(s); 1241 gen_op_ld_v(s, ot, s->T1, s->A0); 1242 gen_string_movl_A0_ESI(s); 1243 gen_op_ld_v(s, ot, s->T0, s->A0); 1244 tcg_gen_mov_tl(cpu_cc_src, s->T1); 1245 tcg_gen_mov_tl(s->cc_srcT, s->T0); 1246 tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1); 1247 set_cc_op(s, CC_OP_SUBB + ot); 1248 1249 dshift = gen_compute_Dshift(s, ot); 1250 gen_op_add_reg(s, s->aflag, R_ESI, dshift); 1251 gen_op_add_reg(s, s->aflag, R_EDI, dshift); 1252 } 1253 1254 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot) 1255 { 1256 if (s->flags & HF_IOBPT_MASK) { 1257 #ifdef CONFIG_USER_ONLY 1258 /* user-mode cpu should not be in IOBPT mode */ 1259 g_assert_not_reached(); 1260 #else 1261 TCGv_i32 t_size = tcg_constant_i32(1 << ot); 1262 TCGv t_next = eip_next_tl(s); 1263 gen_helper_bpt_io(tcg_env, t_port, t_size, t_next); 1264 #endif /* CONFIG_USER_ONLY */ 1265 } 1266 } 1267 1268 static void gen_ins(DisasContext *s, MemOp ot) 1269 { 1270 gen_string_movl_A0_EDI(s); 1271 /* Note: we must do this dummy write first to be restartable in 1272 case of page fault. */ 1273 tcg_gen_movi_tl(s->T0, 0); 1274 gen_op_st_v(s, ot, s->T0, s->A0); 1275 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 1276 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); 1277 gen_helper_in_func(ot, s->T0, s->tmp2_i32); 1278 gen_op_st_v(s, ot, s->T0, s->A0); 1279 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot)); 1280 gen_bpt_io(s, s->tmp2_i32, ot); 1281 } 1282 1283 static void gen_outs(DisasContext *s, MemOp ot) 1284 { 1285 gen_string_movl_A0_ESI(s); 1286 gen_op_ld_v(s, ot, s->T0, s->A0); 1287 1288 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 1289 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); 1290 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0); 1291 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 1292 gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot)); 1293 gen_bpt_io(s, s->tmp2_i32, ot); 1294 } 1295 1296 /* Generate jumps to current or next instruction */ 1297 static void gen_repz(DisasContext *s, MemOp ot, 1298 void (*fn)(DisasContext *s, MemOp ot)) 1299 { 1300 TCGLabel *l2; 1301 l2 = gen_jz_ecx_string(s); 1302 fn(s, ot); 1303 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 1304 /* 1305 * A loop would cause two single step exceptions if ECX = 1 1306 * before rep string_insn 1307 */ 1308 if (s->repz_opt) { 1309 gen_op_jz_ecx(s, l2); 1310 } 1311 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1312 } 1313 1314 #define GEN_REPZ(op) \ 1315 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot) \ 1316 { gen_repz(s, ot, gen_##op); } 1317 1318 static void gen_repz2(DisasContext *s, MemOp ot, int nz, 1319 void (*fn)(DisasContext *s, MemOp ot)) 1320 { 1321 TCGLabel *l2; 1322 l2 = gen_jz_ecx_string(s); 1323 fn(s, ot); 1324 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 1325 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); 1326 if (s->repz_opt) { 1327 gen_op_jz_ecx(s, l2); 1328 } 1329 /* 1330 * Only one iteration is done at a time, so the translation 1331 * block ends unconditionally after this instruction and there 1332 * is no control flow junction - no need to set CC_OP_DYNAMIC. 1333 */ 1334 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1335 } 1336 1337 #define GEN_REPZ2(op) \ 1338 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, int nz) \ 1339 { gen_repz2(s, ot, nz, gen_##op); } 1340 1341 GEN_REPZ(movs) 1342 GEN_REPZ(stos) 1343 GEN_REPZ(lods) 1344 GEN_REPZ(ins) 1345 GEN_REPZ(outs) 1346 GEN_REPZ2(scas) 1347 GEN_REPZ2(cmps) 1348 1349 static void gen_helper_fp_arith_ST0_FT0(int op) 1350 { 1351 switch (op) { 1352 case 0: 1353 gen_helper_fadd_ST0_FT0(tcg_env); 1354 break; 1355 case 1: 1356 gen_helper_fmul_ST0_FT0(tcg_env); 1357 break; 1358 case 2: 1359 gen_helper_fcom_ST0_FT0(tcg_env); 1360 break; 1361 case 3: 1362 gen_helper_fcom_ST0_FT0(tcg_env); 1363 break; 1364 case 4: 1365 gen_helper_fsub_ST0_FT0(tcg_env); 1366 break; 1367 case 5: 1368 gen_helper_fsubr_ST0_FT0(tcg_env); 1369 break; 1370 case 6: 1371 gen_helper_fdiv_ST0_FT0(tcg_env); 1372 break; 1373 case 7: 1374 gen_helper_fdivr_ST0_FT0(tcg_env); 1375 break; 1376 } 1377 } 1378 1379 /* NOTE the exception in "r" op ordering */ 1380 static void gen_helper_fp_arith_STN_ST0(int op, int opreg) 1381 { 1382 TCGv_i32 tmp = tcg_constant_i32(opreg); 1383 switch (op) { 1384 case 0: 1385 gen_helper_fadd_STN_ST0(tcg_env, tmp); 1386 break; 1387 case 1: 1388 gen_helper_fmul_STN_ST0(tcg_env, tmp); 1389 break; 1390 case 4: 1391 gen_helper_fsubr_STN_ST0(tcg_env, tmp); 1392 break; 1393 case 5: 1394 gen_helper_fsub_STN_ST0(tcg_env, tmp); 1395 break; 1396 case 6: 1397 gen_helper_fdivr_STN_ST0(tcg_env, tmp); 1398 break; 1399 case 7: 1400 gen_helper_fdiv_STN_ST0(tcg_env, tmp); 1401 break; 1402 } 1403 } 1404 1405 static void gen_exception(DisasContext *s, int trapno) 1406 { 1407 gen_update_cc_op(s); 1408 gen_update_eip_cur(s); 1409 gen_helper_raise_exception(tcg_env, tcg_constant_i32(trapno)); 1410 s->base.is_jmp = DISAS_NORETURN; 1411 } 1412 1413 /* Generate #UD for the current instruction. The assumption here is that 1414 the instruction is known, but it isn't allowed in the current cpu mode. */ 1415 static void gen_illegal_opcode(DisasContext *s) 1416 { 1417 gen_exception(s, EXCP06_ILLOP); 1418 } 1419 1420 /* Generate #GP for the current instruction. */ 1421 static void gen_exception_gpf(DisasContext *s) 1422 { 1423 gen_exception(s, EXCP0D_GPF); 1424 } 1425 1426 /* Check for cpl == 0; if not, raise #GP and return false. */ 1427 static bool check_cpl0(DisasContext *s) 1428 { 1429 if (CPL(s) == 0) { 1430 return true; 1431 } 1432 gen_exception_gpf(s); 1433 return false; 1434 } 1435 1436 static void gen_shift_flags(DisasContext *s, MemOp ot, TCGv result, 1437 TCGv shm1, TCGv count, bool is_right) 1438 { 1439 TCGv_i32 z32, s32, oldop; 1440 TCGv z_tl; 1441 1442 /* Store the results into the CC variables. If we know that the 1443 variable must be dead, store unconditionally. Otherwise we'll 1444 need to not disrupt the current contents. */ 1445 z_tl = tcg_constant_tl(0); 1446 if (cc_op_live[s->cc_op] & USES_CC_DST) { 1447 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl, 1448 result, cpu_cc_dst); 1449 } else { 1450 tcg_gen_mov_tl(cpu_cc_dst, result); 1451 } 1452 if (cc_op_live[s->cc_op] & USES_CC_SRC) { 1453 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl, 1454 shm1, cpu_cc_src); 1455 } else { 1456 tcg_gen_mov_tl(cpu_cc_src, shm1); 1457 } 1458 1459 /* Get the two potential CC_OP values into temporaries. */ 1460 tcg_gen_movi_i32(s->tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot); 1461 if (s->cc_op == CC_OP_DYNAMIC) { 1462 oldop = cpu_cc_op; 1463 } else { 1464 tcg_gen_movi_i32(s->tmp3_i32, s->cc_op); 1465 oldop = s->tmp3_i32; 1466 } 1467 1468 /* Conditionally store the CC_OP value. */ 1469 z32 = tcg_constant_i32(0); 1470 s32 = tcg_temp_new_i32(); 1471 tcg_gen_trunc_tl_i32(s32, count); 1472 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, s->tmp2_i32, oldop); 1473 1474 /* The CC_OP value is no longer predictable. */ 1475 set_cc_op(s, CC_OP_DYNAMIC); 1476 } 1477 1478 /* XXX: add faster immediate case */ 1479 static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1, 1480 bool is_right, TCGv count_in) 1481 { 1482 target_ulong mask = (ot == MO_64 ? 63 : 31); 1483 TCGv count; 1484 1485 /* load */ 1486 if (op1 == OR_TMP0) { 1487 gen_op_ld_v(s, ot, s->T0, s->A0); 1488 } else { 1489 gen_op_mov_v_reg(s, ot, s->T0, op1); 1490 } 1491 1492 count = tcg_temp_new(); 1493 tcg_gen_andi_tl(count, count_in, mask); 1494 1495 switch (ot) { 1496 case MO_16: 1497 /* Note: we implement the Intel behaviour for shift count > 16. 1498 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A 1499 portion by constructing it as a 32-bit value. */ 1500 if (is_right) { 1501 tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16); 1502 tcg_gen_mov_tl(s->T1, s->T0); 1503 tcg_gen_mov_tl(s->T0, s->tmp0); 1504 } else { 1505 tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16); 1506 } 1507 /* 1508 * If TARGET_X86_64 defined then fall through into MO_32 case, 1509 * otherwise fall through default case. 1510 */ 1511 case MO_32: 1512 #ifdef TARGET_X86_64 1513 /* Concatenate the two 32-bit values and use a 64-bit shift. */ 1514 tcg_gen_subi_tl(s->tmp0, count, 1); 1515 if (is_right) { 1516 tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1); 1517 tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0); 1518 tcg_gen_shr_i64(s->T0, s->T0, count); 1519 } else { 1520 tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0); 1521 tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0); 1522 tcg_gen_shl_i64(s->T0, s->T0, count); 1523 tcg_gen_shri_i64(s->tmp0, s->tmp0, 32); 1524 tcg_gen_shri_i64(s->T0, s->T0, 32); 1525 } 1526 break; 1527 #endif 1528 default: 1529 tcg_gen_subi_tl(s->tmp0, count, 1); 1530 if (is_right) { 1531 tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0); 1532 1533 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1534 tcg_gen_shr_tl(s->T0, s->T0, count); 1535 tcg_gen_shl_tl(s->T1, s->T1, s->tmp4); 1536 } else { 1537 tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0); 1538 if (ot == MO_16) { 1539 /* Only needed if count > 16, for Intel behaviour. */ 1540 tcg_gen_subfi_tl(s->tmp4, 33, count); 1541 tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4); 1542 tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4); 1543 } 1544 1545 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1546 tcg_gen_shl_tl(s->T0, s->T0, count); 1547 tcg_gen_shr_tl(s->T1, s->T1, s->tmp4); 1548 } 1549 tcg_gen_movi_tl(s->tmp4, 0); 1550 tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4, 1551 s->tmp4, s->T1); 1552 tcg_gen_or_tl(s->T0, s->T0, s->T1); 1553 break; 1554 } 1555 1556 /* store */ 1557 gen_op_st_rm_T0_A0(s, ot, op1); 1558 1559 gen_shift_flags(s, ot, s->T0, s->tmp0, count, is_right); 1560 } 1561 1562 #define X86_MAX_INSN_LENGTH 15 1563 1564 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes) 1565 { 1566 uint64_t pc = s->pc; 1567 1568 /* This is a subsequent insn that crosses a page boundary. */ 1569 if (s->base.num_insns > 1 && 1570 !is_same_page(&s->base, s->pc + num_bytes - 1)) { 1571 siglongjmp(s->jmpbuf, 2); 1572 } 1573 1574 s->pc += num_bytes; 1575 if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) { 1576 /* If the instruction's 16th byte is on a different page than the 1st, a 1577 * page fault on the second page wins over the general protection fault 1578 * caused by the instruction being too long. 1579 * This can happen even if the operand is only one byte long! 1580 */ 1581 if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) { 1582 volatile uint8_t unused = 1583 cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK); 1584 (void) unused; 1585 } 1586 siglongjmp(s->jmpbuf, 1); 1587 } 1588 1589 return pc; 1590 } 1591 1592 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s) 1593 { 1594 return translator_ldub(env, &s->base, advance_pc(env, s, 1)); 1595 } 1596 1597 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s) 1598 { 1599 return translator_lduw(env, &s->base, advance_pc(env, s, 2)); 1600 } 1601 1602 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s) 1603 { 1604 return translator_ldl(env, &s->base, advance_pc(env, s, 4)); 1605 } 1606 1607 #ifdef TARGET_X86_64 1608 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s) 1609 { 1610 return translator_ldq(env, &s->base, advance_pc(env, s, 8)); 1611 } 1612 #endif 1613 1614 /* Decompose an address. */ 1615 1616 typedef struct AddressParts { 1617 int def_seg; 1618 int base; 1619 int index; 1620 int scale; 1621 target_long disp; 1622 } AddressParts; 1623 1624 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s, 1625 int modrm) 1626 { 1627 int def_seg, base, index, scale, mod, rm; 1628 target_long disp; 1629 bool havesib; 1630 1631 def_seg = R_DS; 1632 index = -1; 1633 scale = 0; 1634 disp = 0; 1635 1636 mod = (modrm >> 6) & 3; 1637 rm = modrm & 7; 1638 base = rm | REX_B(s); 1639 1640 if (mod == 3) { 1641 /* Normally filtered out earlier, but including this path 1642 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */ 1643 goto done; 1644 } 1645 1646 switch (s->aflag) { 1647 case MO_64: 1648 case MO_32: 1649 havesib = 0; 1650 if (rm == 4) { 1651 int code = x86_ldub_code(env, s); 1652 scale = (code >> 6) & 3; 1653 index = ((code >> 3) & 7) | REX_X(s); 1654 if (index == 4) { 1655 index = -1; /* no index */ 1656 } 1657 base = (code & 7) | REX_B(s); 1658 havesib = 1; 1659 } 1660 1661 switch (mod) { 1662 case 0: 1663 if ((base & 7) == 5) { 1664 base = -1; 1665 disp = (int32_t)x86_ldl_code(env, s); 1666 if (CODE64(s) && !havesib) { 1667 base = -2; 1668 disp += s->pc + s->rip_offset; 1669 } 1670 } 1671 break; 1672 case 1: 1673 disp = (int8_t)x86_ldub_code(env, s); 1674 break; 1675 default: 1676 case 2: 1677 disp = (int32_t)x86_ldl_code(env, s); 1678 break; 1679 } 1680 1681 /* For correct popl handling with esp. */ 1682 if (base == R_ESP && s->popl_esp_hack) { 1683 disp += s->popl_esp_hack; 1684 } 1685 if (base == R_EBP || base == R_ESP) { 1686 def_seg = R_SS; 1687 } 1688 break; 1689 1690 case MO_16: 1691 if (mod == 0) { 1692 if (rm == 6) { 1693 base = -1; 1694 disp = x86_lduw_code(env, s); 1695 break; 1696 } 1697 } else if (mod == 1) { 1698 disp = (int8_t)x86_ldub_code(env, s); 1699 } else { 1700 disp = (int16_t)x86_lduw_code(env, s); 1701 } 1702 1703 switch (rm) { 1704 case 0: 1705 base = R_EBX; 1706 index = R_ESI; 1707 break; 1708 case 1: 1709 base = R_EBX; 1710 index = R_EDI; 1711 break; 1712 case 2: 1713 base = R_EBP; 1714 index = R_ESI; 1715 def_seg = R_SS; 1716 break; 1717 case 3: 1718 base = R_EBP; 1719 index = R_EDI; 1720 def_seg = R_SS; 1721 break; 1722 case 4: 1723 base = R_ESI; 1724 break; 1725 case 5: 1726 base = R_EDI; 1727 break; 1728 case 6: 1729 base = R_EBP; 1730 def_seg = R_SS; 1731 break; 1732 default: 1733 case 7: 1734 base = R_EBX; 1735 break; 1736 } 1737 break; 1738 1739 default: 1740 g_assert_not_reached(); 1741 } 1742 1743 done: 1744 return (AddressParts){ def_seg, base, index, scale, disp }; 1745 } 1746 1747 /* Compute the address, with a minimum number of TCG ops. */ 1748 static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib) 1749 { 1750 TCGv ea = NULL; 1751 1752 if (a.index >= 0 && !is_vsib) { 1753 if (a.scale == 0) { 1754 ea = cpu_regs[a.index]; 1755 } else { 1756 tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale); 1757 ea = s->A0; 1758 } 1759 if (a.base >= 0) { 1760 tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]); 1761 ea = s->A0; 1762 } 1763 } else if (a.base >= 0) { 1764 ea = cpu_regs[a.base]; 1765 } 1766 if (!ea) { 1767 if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) { 1768 /* With cpu_eip ~= pc_save, the expression is pc-relative. */ 1769 tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save); 1770 } else { 1771 tcg_gen_movi_tl(s->A0, a.disp); 1772 } 1773 ea = s->A0; 1774 } else if (a.disp != 0) { 1775 tcg_gen_addi_tl(s->A0, ea, a.disp); 1776 ea = s->A0; 1777 } 1778 1779 return ea; 1780 } 1781 1782 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) 1783 { 1784 AddressParts a = gen_lea_modrm_0(env, s, modrm); 1785 TCGv ea = gen_lea_modrm_1(s, a, false); 1786 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override); 1787 } 1788 1789 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm) 1790 { 1791 (void)gen_lea_modrm_0(env, s, modrm); 1792 } 1793 1794 /* Used for BNDCL, BNDCU, BNDCN. */ 1795 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm, 1796 TCGCond cond, TCGv_i64 bndv) 1797 { 1798 AddressParts a = gen_lea_modrm_0(env, s, modrm); 1799 TCGv ea = gen_lea_modrm_1(s, a, false); 1800 1801 tcg_gen_extu_tl_i64(s->tmp1_i64, ea); 1802 if (!CODE64(s)) { 1803 tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64); 1804 } 1805 tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv); 1806 tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64); 1807 gen_helper_bndck(tcg_env, s->tmp2_i32); 1808 } 1809 1810 /* used for LEA and MOV AX, mem */ 1811 static void gen_add_A0_ds_seg(DisasContext *s) 1812 { 1813 gen_lea_v_seg(s, s->aflag, s->A0, R_DS, s->override); 1814 } 1815 1816 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg == 1817 OR_TMP0 */ 1818 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm, 1819 MemOp ot, int reg, int is_store) 1820 { 1821 int mod, rm; 1822 1823 mod = (modrm >> 6) & 3; 1824 rm = (modrm & 7) | REX_B(s); 1825 if (mod == 3) { 1826 if (is_store) { 1827 if (reg != OR_TMP0) 1828 gen_op_mov_v_reg(s, ot, s->T0, reg); 1829 gen_op_mov_reg_v(s, ot, rm, s->T0); 1830 } else { 1831 gen_op_mov_v_reg(s, ot, s->T0, rm); 1832 if (reg != OR_TMP0) 1833 gen_op_mov_reg_v(s, ot, reg, s->T0); 1834 } 1835 } else { 1836 gen_lea_modrm(env, s, modrm); 1837 if (is_store) { 1838 if (reg != OR_TMP0) 1839 gen_op_mov_v_reg(s, ot, s->T0, reg); 1840 gen_op_st_v(s, ot, s->T0, s->A0); 1841 } else { 1842 gen_op_ld_v(s, ot, s->T0, s->A0); 1843 if (reg != OR_TMP0) 1844 gen_op_mov_reg_v(s, ot, reg, s->T0); 1845 } 1846 } 1847 } 1848 1849 static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot) 1850 { 1851 target_ulong ret; 1852 1853 switch (ot) { 1854 case MO_8: 1855 ret = x86_ldub_code(env, s); 1856 break; 1857 case MO_16: 1858 ret = x86_lduw_code(env, s); 1859 break; 1860 case MO_32: 1861 ret = x86_ldl_code(env, s); 1862 break; 1863 #ifdef TARGET_X86_64 1864 case MO_64: 1865 ret = x86_ldq_code(env, s); 1866 break; 1867 #endif 1868 default: 1869 g_assert_not_reached(); 1870 } 1871 return ret; 1872 } 1873 1874 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot) 1875 { 1876 uint32_t ret; 1877 1878 switch (ot) { 1879 case MO_8: 1880 ret = x86_ldub_code(env, s); 1881 break; 1882 case MO_16: 1883 ret = x86_lduw_code(env, s); 1884 break; 1885 case MO_32: 1886 #ifdef TARGET_X86_64 1887 case MO_64: 1888 #endif 1889 ret = x86_ldl_code(env, s); 1890 break; 1891 default: 1892 g_assert_not_reached(); 1893 } 1894 return ret; 1895 } 1896 1897 static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot) 1898 { 1899 target_long ret; 1900 1901 switch (ot) { 1902 case MO_8: 1903 ret = (int8_t) x86_ldub_code(env, s); 1904 break; 1905 case MO_16: 1906 ret = (int16_t) x86_lduw_code(env, s); 1907 break; 1908 case MO_32: 1909 ret = (int32_t) x86_ldl_code(env, s); 1910 break; 1911 #ifdef TARGET_X86_64 1912 case MO_64: 1913 ret = x86_ldq_code(env, s); 1914 break; 1915 #endif 1916 default: 1917 g_assert_not_reached(); 1918 } 1919 return ret; 1920 } 1921 1922 static void gen_conditional_jump_labels(DisasContext *s, target_long diff, 1923 TCGLabel *not_taken, TCGLabel *taken) 1924 { 1925 if (not_taken) { 1926 gen_set_label(not_taken); 1927 } 1928 gen_jmp_rel_csize(s, 0, 1); 1929 1930 gen_set_label(taken); 1931 gen_jmp_rel(s, s->dflag, diff, 0); 1932 } 1933 1934 static void gen_jcc(DisasContext *s, int b, int diff) 1935 { 1936 TCGLabel *l1 = gen_new_label(); 1937 1938 gen_jcc1(s, b, l1); 1939 gen_conditional_jump_labels(s, diff, NULL, l1); 1940 } 1941 1942 static void gen_cmovcc1(DisasContext *s, int b, TCGv dest, TCGv src) 1943 { 1944 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1945 1946 if (!cc.use_reg2) { 1947 cc.reg2 = tcg_constant_tl(cc.imm); 1948 } 1949 1950 tcg_gen_movcond_tl(cc.cond, dest, cc.reg, cc.reg2, src, dest); 1951 } 1952 1953 static void gen_op_movl_seg_real(DisasContext *s, X86Seg seg_reg, TCGv seg) 1954 { 1955 TCGv selector = tcg_temp_new(); 1956 tcg_gen_ext16u_tl(selector, seg); 1957 tcg_gen_st32_tl(selector, tcg_env, 1958 offsetof(CPUX86State,segs[seg_reg].selector)); 1959 tcg_gen_shli_tl(cpu_seg_base[seg_reg], selector, 4); 1960 } 1961 1962 /* move SRC to seg_reg and compute if the CPU state may change. Never 1963 call this function with seg_reg == R_CS */ 1964 static void gen_movl_seg(DisasContext *s, X86Seg seg_reg, TCGv src) 1965 { 1966 if (PE(s) && !VM86(s)) { 1967 tcg_gen_trunc_tl_i32(s->tmp2_i32, src); 1968 gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32); 1969 /* abort translation because the addseg value may change or 1970 because ss32 may change. For R_SS, translation must always 1971 stop as a special handling must be done to disable hardware 1972 interrupts for the next instruction */ 1973 if (seg_reg == R_SS) { 1974 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 1975 } else if (CODE32(s) && seg_reg < R_FS) { 1976 s->base.is_jmp = DISAS_EOB_NEXT; 1977 } 1978 } else { 1979 gen_op_movl_seg_real(s, seg_reg, src); 1980 if (seg_reg == R_SS) { 1981 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 1982 } 1983 } 1984 } 1985 1986 static void gen_far_call(DisasContext *s) 1987 { 1988 TCGv_i32 new_cs = tcg_temp_new_i32(); 1989 tcg_gen_trunc_tl_i32(new_cs, s->T1); 1990 if (PE(s) && !VM86(s)) { 1991 gen_helper_lcall_protected(tcg_env, new_cs, s->T0, 1992 tcg_constant_i32(s->dflag - 1), 1993 eip_next_tl(s)); 1994 } else { 1995 TCGv_i32 new_eip = tcg_temp_new_i32(); 1996 tcg_gen_trunc_tl_i32(new_eip, s->T0); 1997 gen_helper_lcall_real(tcg_env, new_cs, new_eip, 1998 tcg_constant_i32(s->dflag - 1), 1999 eip_next_i32(s)); 2000 } 2001 s->base.is_jmp = DISAS_JUMP; 2002 } 2003 2004 static void gen_far_jmp(DisasContext *s) 2005 { 2006 if (PE(s) && !VM86(s)) { 2007 TCGv_i32 new_cs = tcg_temp_new_i32(); 2008 tcg_gen_trunc_tl_i32(new_cs, s->T1); 2009 gen_helper_ljmp_protected(tcg_env, new_cs, s->T0, 2010 eip_next_tl(s)); 2011 } else { 2012 gen_op_movl_seg_real(s, R_CS, s->T1); 2013 gen_op_jmp_v(s, s->T0); 2014 } 2015 s->base.is_jmp = DISAS_JUMP; 2016 } 2017 2018 static void gen_svm_check_intercept(DisasContext *s, uint32_t type) 2019 { 2020 /* no SVM activated; fast case */ 2021 if (likely(!GUEST(s))) { 2022 return; 2023 } 2024 gen_helper_svm_check_intercept(tcg_env, tcg_constant_i32(type)); 2025 } 2026 2027 static inline void gen_stack_update(DisasContext *s, int addend) 2028 { 2029 gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend); 2030 } 2031 2032 /* Generate a push. It depends on ss32, addseg and dflag. */ 2033 static void gen_push_v(DisasContext *s, TCGv val) 2034 { 2035 MemOp d_ot = mo_pushpop(s, s->dflag); 2036 MemOp a_ot = mo_stacksize(s); 2037 int size = 1 << d_ot; 2038 TCGv new_esp = s->A0; 2039 2040 tcg_gen_subi_tl(s->A0, cpu_regs[R_ESP], size); 2041 2042 if (!CODE64(s)) { 2043 if (ADDSEG(s)) { 2044 new_esp = tcg_temp_new(); 2045 tcg_gen_mov_tl(new_esp, s->A0); 2046 } 2047 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2048 } 2049 2050 gen_op_st_v(s, d_ot, val, s->A0); 2051 gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp); 2052 } 2053 2054 /* two step pop is necessary for precise exceptions */ 2055 static MemOp gen_pop_T0(DisasContext *s) 2056 { 2057 MemOp d_ot = mo_pushpop(s, s->dflag); 2058 2059 gen_lea_v_seg_dest(s, mo_stacksize(s), s->T0, cpu_regs[R_ESP], R_SS, -1); 2060 gen_op_ld_v(s, d_ot, s->T0, s->T0); 2061 2062 return d_ot; 2063 } 2064 2065 static inline void gen_pop_update(DisasContext *s, MemOp ot) 2066 { 2067 gen_stack_update(s, 1 << ot); 2068 } 2069 2070 static inline void gen_stack_A0(DisasContext *s) 2071 { 2072 gen_lea_v_seg(s, SS32(s) ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1); 2073 } 2074 2075 static void gen_pusha(DisasContext *s) 2076 { 2077 MemOp s_ot = SS32(s) ? MO_32 : MO_16; 2078 MemOp d_ot = s->dflag; 2079 int size = 1 << d_ot; 2080 int i; 2081 2082 for (i = 0; i < 8; i++) { 2083 tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], (i - 8) * size); 2084 gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1); 2085 gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0); 2086 } 2087 2088 gen_stack_update(s, -8 * size); 2089 } 2090 2091 static void gen_popa(DisasContext *s) 2092 { 2093 MemOp s_ot = SS32(s) ? MO_32 : MO_16; 2094 MemOp d_ot = s->dflag; 2095 int size = 1 << d_ot; 2096 int i; 2097 2098 for (i = 0; i < 8; i++) { 2099 /* ESP is not reloaded */ 2100 if (7 - i == R_ESP) { 2101 continue; 2102 } 2103 tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], i * size); 2104 gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1); 2105 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2106 gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0); 2107 } 2108 2109 gen_stack_update(s, 8 * size); 2110 } 2111 2112 static void gen_enter(DisasContext *s, int esp_addend, int level) 2113 { 2114 MemOp d_ot = mo_pushpop(s, s->dflag); 2115 MemOp a_ot = CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16; 2116 int size = 1 << d_ot; 2117 2118 /* Push BP; compute FrameTemp into T1. */ 2119 tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size); 2120 gen_lea_v_seg(s, a_ot, s->T1, R_SS, -1); 2121 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0); 2122 2123 level &= 31; 2124 if (level != 0) { 2125 int i; 2126 2127 /* Copy level-1 pointers from the previous frame. */ 2128 for (i = 1; i < level; ++i) { 2129 tcg_gen_subi_tl(s->A0, cpu_regs[R_EBP], size * i); 2130 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2131 gen_op_ld_v(s, d_ot, s->tmp0, s->A0); 2132 2133 tcg_gen_subi_tl(s->A0, s->T1, size * i); 2134 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2135 gen_op_st_v(s, d_ot, s->tmp0, s->A0); 2136 } 2137 2138 /* Push the current FrameTemp as the last level. */ 2139 tcg_gen_subi_tl(s->A0, s->T1, size * level); 2140 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2141 gen_op_st_v(s, d_ot, s->T1, s->A0); 2142 } 2143 2144 /* Copy the FrameTemp value to EBP. */ 2145 gen_op_mov_reg_v(s, a_ot, R_EBP, s->T1); 2146 2147 /* Compute the final value of ESP. */ 2148 tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level); 2149 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2150 } 2151 2152 static void gen_leave(DisasContext *s) 2153 { 2154 MemOp d_ot = mo_pushpop(s, s->dflag); 2155 MemOp a_ot = mo_stacksize(s); 2156 2157 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1); 2158 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2159 2160 tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot); 2161 2162 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0); 2163 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2164 } 2165 2166 /* Similarly, except that the assumption here is that we don't decode 2167 the instruction at all -- either a missing opcode, an unimplemented 2168 feature, or just a bogus instruction stream. */ 2169 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) 2170 { 2171 gen_illegal_opcode(s); 2172 2173 if (qemu_loglevel_mask(LOG_UNIMP)) { 2174 FILE *logfile = qemu_log_trylock(); 2175 if (logfile) { 2176 target_ulong pc = s->base.pc_next, end = s->pc; 2177 2178 fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc); 2179 for (; pc < end; ++pc) { 2180 fprintf(logfile, " %02x", cpu_ldub_code(env, pc)); 2181 } 2182 fprintf(logfile, "\n"); 2183 qemu_log_unlock(logfile); 2184 } 2185 } 2186 } 2187 2188 /* an interrupt is different from an exception because of the 2189 privilege checks */ 2190 static void gen_interrupt(DisasContext *s, uint8_t intno) 2191 { 2192 gen_update_cc_op(s); 2193 gen_update_eip_cur(s); 2194 gen_helper_raise_interrupt(tcg_env, tcg_constant_i32(intno), 2195 cur_insn_len_i32(s)); 2196 s->base.is_jmp = DISAS_NORETURN; 2197 } 2198 2199 static void gen_set_hflag(DisasContext *s, uint32_t mask) 2200 { 2201 if ((s->flags & mask) == 0) { 2202 TCGv_i32 t = tcg_temp_new_i32(); 2203 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2204 tcg_gen_ori_i32(t, t, mask); 2205 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2206 s->flags |= mask; 2207 } 2208 } 2209 2210 static void gen_reset_hflag(DisasContext *s, uint32_t mask) 2211 { 2212 if (s->flags & mask) { 2213 TCGv_i32 t = tcg_temp_new_i32(); 2214 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2215 tcg_gen_andi_i32(t, t, ~mask); 2216 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2217 s->flags &= ~mask; 2218 } 2219 } 2220 2221 static void gen_set_eflags(DisasContext *s, target_ulong mask) 2222 { 2223 TCGv t = tcg_temp_new(); 2224 2225 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2226 tcg_gen_ori_tl(t, t, mask); 2227 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2228 } 2229 2230 static void gen_reset_eflags(DisasContext *s, target_ulong mask) 2231 { 2232 TCGv t = tcg_temp_new(); 2233 2234 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2235 tcg_gen_andi_tl(t, t, ~mask); 2236 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2237 } 2238 2239 /* Clear BND registers during legacy branches. */ 2240 static void gen_bnd_jmp(DisasContext *s) 2241 { 2242 /* Clear the registers only if BND prefix is missing, MPX is enabled, 2243 and if the BNDREGs are known to be in use (non-zero) already. 2244 The helper itself will check BNDPRESERVE at runtime. */ 2245 if ((s->prefix & PREFIX_REPNZ) == 0 2246 && (s->flags & HF_MPX_EN_MASK) != 0 2247 && (s->flags & HF_MPX_IU_MASK) != 0) { 2248 gen_helper_bnd_jmp(tcg_env); 2249 } 2250 } 2251 2252 /* Generate an end of block. Trace exception is also generated if needed. 2253 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. 2254 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of 2255 S->TF. This is used by the syscall/sysret insns. */ 2256 static void 2257 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr) 2258 { 2259 bool inhibit_reset; 2260 2261 gen_update_cc_op(s); 2262 2263 /* If several instructions disable interrupts, only the first does it. */ 2264 inhibit_reset = false; 2265 if (s->flags & HF_INHIBIT_IRQ_MASK) { 2266 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); 2267 inhibit_reset = true; 2268 } else if (inhibit) { 2269 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); 2270 } 2271 2272 if (s->base.tb->flags & HF_RF_MASK) { 2273 gen_reset_eflags(s, RF_MASK); 2274 } 2275 if (recheck_tf) { 2276 gen_helper_rechecking_single_step(tcg_env); 2277 tcg_gen_exit_tb(NULL, 0); 2278 } else if (s->flags & HF_TF_MASK) { 2279 gen_helper_single_step(tcg_env); 2280 } else if (jr && 2281 /* give irqs a chance to happen */ 2282 !inhibit_reset) { 2283 tcg_gen_lookup_and_goto_ptr(); 2284 } else { 2285 tcg_gen_exit_tb(NULL, 0); 2286 } 2287 s->base.is_jmp = DISAS_NORETURN; 2288 } 2289 2290 static inline void 2291 gen_eob_syscall(DisasContext *s) 2292 { 2293 gen_eob_worker(s, false, true, false); 2294 } 2295 2296 /* End of block. Set HF_INHIBIT_IRQ_MASK if it isn't already set. */ 2297 static void gen_eob_inhibit_irq(DisasContext *s) 2298 { 2299 gen_eob_worker(s, true, false, false); 2300 } 2301 2302 /* End of block, resetting the inhibit irq flag. */ 2303 static void gen_eob(DisasContext *s) 2304 { 2305 gen_eob_worker(s, false, false, false); 2306 } 2307 2308 /* Jump to register */ 2309 static void gen_jr(DisasContext *s) 2310 { 2311 gen_eob_worker(s, false, false, true); 2312 } 2313 2314 /* Jump to eip+diff, truncating the result to OT. */ 2315 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num) 2316 { 2317 bool use_goto_tb = s->jmp_opt; 2318 target_ulong mask = -1; 2319 target_ulong new_pc = s->pc + diff; 2320 target_ulong new_eip = new_pc - s->cs_base; 2321 2322 assert(!s->cc_op_dirty); 2323 2324 /* In 64-bit mode, operand size is fixed at 64 bits. */ 2325 if (!CODE64(s)) { 2326 if (ot == MO_16) { 2327 mask = 0xffff; 2328 if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) { 2329 use_goto_tb = false; 2330 } 2331 } else { 2332 mask = 0xffffffff; 2333 } 2334 } 2335 new_eip &= mask; 2336 2337 if (tb_cflags(s->base.tb) & CF_PCREL) { 2338 tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save); 2339 /* 2340 * If we can prove the branch does not leave the page and we have 2341 * no extra masking to apply (data16 branch in code32, see above), 2342 * then we have also proven that the addition does not wrap. 2343 */ 2344 if (!use_goto_tb || !is_same_page(&s->base, new_pc)) { 2345 tcg_gen_andi_tl(cpu_eip, cpu_eip, mask); 2346 use_goto_tb = false; 2347 } 2348 } else if (!CODE64(s)) { 2349 new_pc = (uint32_t)(new_eip + s->cs_base); 2350 } 2351 2352 if (use_goto_tb && translator_use_goto_tb(&s->base, new_pc)) { 2353 /* jump to same page: we can use a direct jump */ 2354 tcg_gen_goto_tb(tb_num); 2355 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2356 tcg_gen_movi_tl(cpu_eip, new_eip); 2357 } 2358 tcg_gen_exit_tb(s->base.tb, tb_num); 2359 s->base.is_jmp = DISAS_NORETURN; 2360 } else { 2361 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2362 tcg_gen_movi_tl(cpu_eip, new_eip); 2363 } 2364 if (s->jmp_opt) { 2365 gen_jr(s); /* jump to another page */ 2366 } else { 2367 gen_eob(s); /* exit to main loop */ 2368 } 2369 } 2370 } 2371 2372 /* Jump to eip+diff, truncating to the current code size. */ 2373 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num) 2374 { 2375 /* CODE64 ignores the OT argument, so we need not consider it. */ 2376 gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num); 2377 } 2378 2379 static inline void gen_ldq_env_A0(DisasContext *s, int offset) 2380 { 2381 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2382 tcg_gen_st_i64(s->tmp1_i64, tcg_env, offset); 2383 } 2384 2385 static inline void gen_stq_env_A0(DisasContext *s, int offset) 2386 { 2387 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, offset); 2388 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2389 } 2390 2391 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align) 2392 { 2393 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2394 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2395 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2396 int mem_index = s->mem_index; 2397 TCGv_i128 t = tcg_temp_new_i128(); 2398 2399 tcg_gen_qemu_ld_i128(t, s->A0, mem_index, mop); 2400 tcg_gen_st_i128(t, tcg_env, offset); 2401 } 2402 2403 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align) 2404 { 2405 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2406 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2407 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2408 int mem_index = s->mem_index; 2409 TCGv_i128 t = tcg_temp_new_i128(); 2410 2411 tcg_gen_ld_i128(t, tcg_env, offset); 2412 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop); 2413 } 2414 2415 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align) 2416 { 2417 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2418 int mem_index = s->mem_index; 2419 TCGv_i128 t0 = tcg_temp_new_i128(); 2420 TCGv_i128 t1 = tcg_temp_new_i128(); 2421 2422 tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2423 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2424 tcg_gen_qemu_ld_i128(t1, s->tmp0, mem_index, mop); 2425 2426 tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2427 tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2428 } 2429 2430 static void gen_sty_env_A0(DisasContext *s, int offset, bool align) 2431 { 2432 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2433 int mem_index = s->mem_index; 2434 TCGv_i128 t = tcg_temp_new_i128(); 2435 2436 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2437 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2438 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2439 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2440 tcg_gen_qemu_st_i128(t, s->tmp0, mem_index, mop); 2441 } 2442 2443 static void gen_cmpxchg8b(DisasContext *s, CPUX86State *env, int modrm) 2444 { 2445 TCGv_i64 cmp, val, old; 2446 TCGv Z; 2447 2448 gen_lea_modrm(env, s, modrm); 2449 2450 cmp = tcg_temp_new_i64(); 2451 val = tcg_temp_new_i64(); 2452 old = tcg_temp_new_i64(); 2453 2454 /* Construct the comparison values from the register pair. */ 2455 tcg_gen_concat_tl_i64(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]); 2456 tcg_gen_concat_tl_i64(val, cpu_regs[R_EBX], cpu_regs[R_ECX]); 2457 2458 /* Only require atomic with LOCK; non-parallel handled in generator. */ 2459 if (s->prefix & PREFIX_LOCK) { 2460 tcg_gen_atomic_cmpxchg_i64(old, s->A0, cmp, val, s->mem_index, MO_TEUQ); 2461 } else { 2462 tcg_gen_nonatomic_cmpxchg_i64(old, s->A0, cmp, val, 2463 s->mem_index, MO_TEUQ); 2464 } 2465 2466 /* Set tmp0 to match the required value of Z. */ 2467 tcg_gen_setcond_i64(TCG_COND_EQ, cmp, old, cmp); 2468 Z = tcg_temp_new(); 2469 tcg_gen_trunc_i64_tl(Z, cmp); 2470 2471 /* 2472 * Extract the result values for the register pair. 2473 * For 32-bit, we may do this unconditionally, because on success (Z=1), 2474 * the old value matches the previous value in EDX:EAX. For x86_64, 2475 * the store must be conditional, because we must leave the source 2476 * registers unchanged on success, and zero-extend the writeback 2477 * on failure (Z=0). 2478 */ 2479 if (TARGET_LONG_BITS == 32) { 2480 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], old); 2481 } else { 2482 TCGv zero = tcg_constant_tl(0); 2483 2484 tcg_gen_extr_i64_tl(s->T0, s->T1, old); 2485 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EAX], Z, zero, 2486 s->T0, cpu_regs[R_EAX]); 2487 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EDX], Z, zero, 2488 s->T1, cpu_regs[R_EDX]); 2489 } 2490 2491 /* Update Z. */ 2492 gen_compute_eflags(s); 2493 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, Z, ctz32(CC_Z), 1); 2494 } 2495 2496 #ifdef TARGET_X86_64 2497 static void gen_cmpxchg16b(DisasContext *s, CPUX86State *env, int modrm) 2498 { 2499 MemOp mop = MO_TE | MO_128 | MO_ALIGN; 2500 TCGv_i64 t0, t1; 2501 TCGv_i128 cmp, val; 2502 2503 gen_lea_modrm(env, s, modrm); 2504 2505 cmp = tcg_temp_new_i128(); 2506 val = tcg_temp_new_i128(); 2507 tcg_gen_concat_i64_i128(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]); 2508 tcg_gen_concat_i64_i128(val, cpu_regs[R_EBX], cpu_regs[R_ECX]); 2509 2510 /* Only require atomic with LOCK; non-parallel handled in generator. */ 2511 if (s->prefix & PREFIX_LOCK) { 2512 tcg_gen_atomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop); 2513 } else { 2514 tcg_gen_nonatomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop); 2515 } 2516 2517 tcg_gen_extr_i128_i64(s->T0, s->T1, val); 2518 2519 /* Determine success after the fact. */ 2520 t0 = tcg_temp_new_i64(); 2521 t1 = tcg_temp_new_i64(); 2522 tcg_gen_xor_i64(t0, s->T0, cpu_regs[R_EAX]); 2523 tcg_gen_xor_i64(t1, s->T1, cpu_regs[R_EDX]); 2524 tcg_gen_or_i64(t0, t0, t1); 2525 2526 /* Update Z. */ 2527 gen_compute_eflags(s); 2528 tcg_gen_setcondi_i64(TCG_COND_EQ, t0, t0, 0); 2529 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, t0, ctz32(CC_Z), 1); 2530 2531 /* 2532 * Extract the result values for the register pair. We may do this 2533 * unconditionally, because on success (Z=1), the old value matches 2534 * the previous value in RDX:RAX. 2535 */ 2536 tcg_gen_mov_i64(cpu_regs[R_EAX], s->T0); 2537 tcg_gen_mov_i64(cpu_regs[R_EDX], s->T1); 2538 } 2539 #endif 2540 2541 static bool disas_insn_x87(DisasContext *s, CPUState *cpu, int b) 2542 { 2543 CPUX86State *env = cpu_env(cpu); 2544 bool update_fip = true; 2545 int modrm, mod, rm, op; 2546 2547 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 2548 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 2549 /* XXX: what to do if illegal op ? */ 2550 gen_exception(s, EXCP07_PREX); 2551 return true; 2552 } 2553 modrm = x86_ldub_code(env, s); 2554 mod = (modrm >> 6) & 3; 2555 rm = modrm & 7; 2556 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 2557 if (mod != 3) { 2558 /* memory op */ 2559 AddressParts a = gen_lea_modrm_0(env, s, modrm); 2560 TCGv ea = gen_lea_modrm_1(s, a, false); 2561 TCGv last_addr = tcg_temp_new(); 2562 bool update_fdp = true; 2563 2564 tcg_gen_mov_tl(last_addr, ea); 2565 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override); 2566 2567 switch (op) { 2568 case 0x00 ... 0x07: /* fxxxs */ 2569 case 0x10 ... 0x17: /* fixxxl */ 2570 case 0x20 ... 0x27: /* fxxxl */ 2571 case 0x30 ... 0x37: /* fixxx */ 2572 { 2573 int op1; 2574 op1 = op & 7; 2575 2576 switch (op >> 4) { 2577 case 0: 2578 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2579 s->mem_index, MO_LEUL); 2580 gen_helper_flds_FT0(tcg_env, s->tmp2_i32); 2581 break; 2582 case 1: 2583 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2584 s->mem_index, MO_LEUL); 2585 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2586 break; 2587 case 2: 2588 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2589 s->mem_index, MO_LEUQ); 2590 gen_helper_fldl_FT0(tcg_env, s->tmp1_i64); 2591 break; 2592 case 3: 2593 default: 2594 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2595 s->mem_index, MO_LESW); 2596 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2597 break; 2598 } 2599 2600 gen_helper_fp_arith_ST0_FT0(op1); 2601 if (op1 == 3) { 2602 /* fcomp needs pop */ 2603 gen_helper_fpop(tcg_env); 2604 } 2605 } 2606 break; 2607 case 0x08: /* flds */ 2608 case 0x0a: /* fsts */ 2609 case 0x0b: /* fstps */ 2610 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 2611 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 2612 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 2613 switch (op & 7) { 2614 case 0: 2615 switch (op >> 4) { 2616 case 0: 2617 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2618 s->mem_index, MO_LEUL); 2619 gen_helper_flds_ST0(tcg_env, s->tmp2_i32); 2620 break; 2621 case 1: 2622 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2623 s->mem_index, MO_LEUL); 2624 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2625 break; 2626 case 2: 2627 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2628 s->mem_index, MO_LEUQ); 2629 gen_helper_fldl_ST0(tcg_env, s->tmp1_i64); 2630 break; 2631 case 3: 2632 default: 2633 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2634 s->mem_index, MO_LESW); 2635 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2636 break; 2637 } 2638 break; 2639 case 1: 2640 /* XXX: the corresponding CPUID bit must be tested ! */ 2641 switch (op >> 4) { 2642 case 1: 2643 gen_helper_fisttl_ST0(s->tmp2_i32, tcg_env); 2644 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2645 s->mem_index, MO_LEUL); 2646 break; 2647 case 2: 2648 gen_helper_fisttll_ST0(s->tmp1_i64, tcg_env); 2649 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2650 s->mem_index, MO_LEUQ); 2651 break; 2652 case 3: 2653 default: 2654 gen_helper_fistt_ST0(s->tmp2_i32, tcg_env); 2655 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2656 s->mem_index, MO_LEUW); 2657 break; 2658 } 2659 gen_helper_fpop(tcg_env); 2660 break; 2661 default: 2662 switch (op >> 4) { 2663 case 0: 2664 gen_helper_fsts_ST0(s->tmp2_i32, tcg_env); 2665 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2666 s->mem_index, MO_LEUL); 2667 break; 2668 case 1: 2669 gen_helper_fistl_ST0(s->tmp2_i32, tcg_env); 2670 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2671 s->mem_index, MO_LEUL); 2672 break; 2673 case 2: 2674 gen_helper_fstl_ST0(s->tmp1_i64, tcg_env); 2675 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2676 s->mem_index, MO_LEUQ); 2677 break; 2678 case 3: 2679 default: 2680 gen_helper_fist_ST0(s->tmp2_i32, tcg_env); 2681 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2682 s->mem_index, MO_LEUW); 2683 break; 2684 } 2685 if ((op & 7) == 3) { 2686 gen_helper_fpop(tcg_env); 2687 } 2688 break; 2689 } 2690 break; 2691 case 0x0c: /* fldenv mem */ 2692 gen_helper_fldenv(tcg_env, s->A0, 2693 tcg_constant_i32(s->dflag - 1)); 2694 update_fip = update_fdp = false; 2695 break; 2696 case 0x0d: /* fldcw mem */ 2697 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2698 s->mem_index, MO_LEUW); 2699 gen_helper_fldcw(tcg_env, s->tmp2_i32); 2700 update_fip = update_fdp = false; 2701 break; 2702 case 0x0e: /* fnstenv mem */ 2703 gen_helper_fstenv(tcg_env, s->A0, 2704 tcg_constant_i32(s->dflag - 1)); 2705 update_fip = update_fdp = false; 2706 break; 2707 case 0x0f: /* fnstcw mem */ 2708 gen_helper_fnstcw(s->tmp2_i32, tcg_env); 2709 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2710 s->mem_index, MO_LEUW); 2711 update_fip = update_fdp = false; 2712 break; 2713 case 0x1d: /* fldt mem */ 2714 gen_helper_fldt_ST0(tcg_env, s->A0); 2715 break; 2716 case 0x1f: /* fstpt mem */ 2717 gen_helper_fstt_ST0(tcg_env, s->A0); 2718 gen_helper_fpop(tcg_env); 2719 break; 2720 case 0x2c: /* frstor mem */ 2721 gen_helper_frstor(tcg_env, s->A0, 2722 tcg_constant_i32(s->dflag - 1)); 2723 update_fip = update_fdp = false; 2724 break; 2725 case 0x2e: /* fnsave mem */ 2726 gen_helper_fsave(tcg_env, s->A0, 2727 tcg_constant_i32(s->dflag - 1)); 2728 update_fip = update_fdp = false; 2729 break; 2730 case 0x2f: /* fnstsw mem */ 2731 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2732 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2733 s->mem_index, MO_LEUW); 2734 update_fip = update_fdp = false; 2735 break; 2736 case 0x3c: /* fbld */ 2737 gen_helper_fbld_ST0(tcg_env, s->A0); 2738 break; 2739 case 0x3e: /* fbstp */ 2740 gen_helper_fbst_ST0(tcg_env, s->A0); 2741 gen_helper_fpop(tcg_env); 2742 break; 2743 case 0x3d: /* fildll */ 2744 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2745 s->mem_index, MO_LEUQ); 2746 gen_helper_fildll_ST0(tcg_env, s->tmp1_i64); 2747 break; 2748 case 0x3f: /* fistpll */ 2749 gen_helper_fistll_ST0(s->tmp1_i64, tcg_env); 2750 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2751 s->mem_index, MO_LEUQ); 2752 gen_helper_fpop(tcg_env); 2753 break; 2754 default: 2755 return false; 2756 } 2757 2758 if (update_fdp) { 2759 int last_seg = s->override >= 0 ? s->override : a.def_seg; 2760 2761 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 2762 offsetof(CPUX86State, 2763 segs[last_seg].selector)); 2764 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 2765 offsetof(CPUX86State, fpds)); 2766 tcg_gen_st_tl(last_addr, tcg_env, 2767 offsetof(CPUX86State, fpdp)); 2768 } 2769 } else { 2770 /* register float ops */ 2771 int opreg = rm; 2772 2773 switch (op) { 2774 case 0x08: /* fld sti */ 2775 gen_helper_fpush(tcg_env); 2776 gen_helper_fmov_ST0_STN(tcg_env, 2777 tcg_constant_i32((opreg + 1) & 7)); 2778 break; 2779 case 0x09: /* fxchg sti */ 2780 case 0x29: /* fxchg4 sti, undocumented op */ 2781 case 0x39: /* fxchg7 sti, undocumented op */ 2782 gen_helper_fxchg_ST0_STN(tcg_env, tcg_constant_i32(opreg)); 2783 break; 2784 case 0x0a: /* grp d9/2 */ 2785 switch (rm) { 2786 case 0: /* fnop */ 2787 /* 2788 * check exceptions (FreeBSD FPU probe) 2789 * needs to be treated as I/O because of ferr_irq 2790 */ 2791 translator_io_start(&s->base); 2792 gen_helper_fwait(tcg_env); 2793 update_fip = false; 2794 break; 2795 default: 2796 return false; 2797 } 2798 break; 2799 case 0x0c: /* grp d9/4 */ 2800 switch (rm) { 2801 case 0: /* fchs */ 2802 gen_helper_fchs_ST0(tcg_env); 2803 break; 2804 case 1: /* fabs */ 2805 gen_helper_fabs_ST0(tcg_env); 2806 break; 2807 case 4: /* ftst */ 2808 gen_helper_fldz_FT0(tcg_env); 2809 gen_helper_fcom_ST0_FT0(tcg_env); 2810 break; 2811 case 5: /* fxam */ 2812 gen_helper_fxam_ST0(tcg_env); 2813 break; 2814 default: 2815 return false; 2816 } 2817 break; 2818 case 0x0d: /* grp d9/5 */ 2819 { 2820 switch (rm) { 2821 case 0: 2822 gen_helper_fpush(tcg_env); 2823 gen_helper_fld1_ST0(tcg_env); 2824 break; 2825 case 1: 2826 gen_helper_fpush(tcg_env); 2827 gen_helper_fldl2t_ST0(tcg_env); 2828 break; 2829 case 2: 2830 gen_helper_fpush(tcg_env); 2831 gen_helper_fldl2e_ST0(tcg_env); 2832 break; 2833 case 3: 2834 gen_helper_fpush(tcg_env); 2835 gen_helper_fldpi_ST0(tcg_env); 2836 break; 2837 case 4: 2838 gen_helper_fpush(tcg_env); 2839 gen_helper_fldlg2_ST0(tcg_env); 2840 break; 2841 case 5: 2842 gen_helper_fpush(tcg_env); 2843 gen_helper_fldln2_ST0(tcg_env); 2844 break; 2845 case 6: 2846 gen_helper_fpush(tcg_env); 2847 gen_helper_fldz_ST0(tcg_env); 2848 break; 2849 default: 2850 return false; 2851 } 2852 } 2853 break; 2854 case 0x0e: /* grp d9/6 */ 2855 switch (rm) { 2856 case 0: /* f2xm1 */ 2857 gen_helper_f2xm1(tcg_env); 2858 break; 2859 case 1: /* fyl2x */ 2860 gen_helper_fyl2x(tcg_env); 2861 break; 2862 case 2: /* fptan */ 2863 gen_helper_fptan(tcg_env); 2864 break; 2865 case 3: /* fpatan */ 2866 gen_helper_fpatan(tcg_env); 2867 break; 2868 case 4: /* fxtract */ 2869 gen_helper_fxtract(tcg_env); 2870 break; 2871 case 5: /* fprem1 */ 2872 gen_helper_fprem1(tcg_env); 2873 break; 2874 case 6: /* fdecstp */ 2875 gen_helper_fdecstp(tcg_env); 2876 break; 2877 default: 2878 case 7: /* fincstp */ 2879 gen_helper_fincstp(tcg_env); 2880 break; 2881 } 2882 break; 2883 case 0x0f: /* grp d9/7 */ 2884 switch (rm) { 2885 case 0: /* fprem */ 2886 gen_helper_fprem(tcg_env); 2887 break; 2888 case 1: /* fyl2xp1 */ 2889 gen_helper_fyl2xp1(tcg_env); 2890 break; 2891 case 2: /* fsqrt */ 2892 gen_helper_fsqrt(tcg_env); 2893 break; 2894 case 3: /* fsincos */ 2895 gen_helper_fsincos(tcg_env); 2896 break; 2897 case 5: /* fscale */ 2898 gen_helper_fscale(tcg_env); 2899 break; 2900 case 4: /* frndint */ 2901 gen_helper_frndint(tcg_env); 2902 break; 2903 case 6: /* fsin */ 2904 gen_helper_fsin(tcg_env); 2905 break; 2906 default: 2907 case 7: /* fcos */ 2908 gen_helper_fcos(tcg_env); 2909 break; 2910 } 2911 break; 2912 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 2913 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 2914 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 2915 { 2916 int op1; 2917 2918 op1 = op & 7; 2919 if (op >= 0x20) { 2920 gen_helper_fp_arith_STN_ST0(op1, opreg); 2921 if (op >= 0x30) { 2922 gen_helper_fpop(tcg_env); 2923 } 2924 } else { 2925 gen_helper_fmov_FT0_STN(tcg_env, 2926 tcg_constant_i32(opreg)); 2927 gen_helper_fp_arith_ST0_FT0(op1); 2928 } 2929 } 2930 break; 2931 case 0x02: /* fcom */ 2932 case 0x22: /* fcom2, undocumented op */ 2933 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2934 gen_helper_fcom_ST0_FT0(tcg_env); 2935 break; 2936 case 0x03: /* fcomp */ 2937 case 0x23: /* fcomp3, undocumented op */ 2938 case 0x32: /* fcomp5, undocumented op */ 2939 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2940 gen_helper_fcom_ST0_FT0(tcg_env); 2941 gen_helper_fpop(tcg_env); 2942 break; 2943 case 0x15: /* da/5 */ 2944 switch (rm) { 2945 case 1: /* fucompp */ 2946 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2947 gen_helper_fucom_ST0_FT0(tcg_env); 2948 gen_helper_fpop(tcg_env); 2949 gen_helper_fpop(tcg_env); 2950 break; 2951 default: 2952 return false; 2953 } 2954 break; 2955 case 0x1c: 2956 switch (rm) { 2957 case 0: /* feni (287 only, just do nop here) */ 2958 break; 2959 case 1: /* fdisi (287 only, just do nop here) */ 2960 break; 2961 case 2: /* fclex */ 2962 gen_helper_fclex(tcg_env); 2963 update_fip = false; 2964 break; 2965 case 3: /* fninit */ 2966 gen_helper_fninit(tcg_env); 2967 update_fip = false; 2968 break; 2969 case 4: /* fsetpm (287 only, just do nop here) */ 2970 break; 2971 default: 2972 return false; 2973 } 2974 break; 2975 case 0x1d: /* fucomi */ 2976 if (!(s->cpuid_features & CPUID_CMOV)) { 2977 goto illegal_op; 2978 } 2979 gen_update_cc_op(s); 2980 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2981 gen_helper_fucomi_ST0_FT0(tcg_env); 2982 set_cc_op(s, CC_OP_EFLAGS); 2983 break; 2984 case 0x1e: /* fcomi */ 2985 if (!(s->cpuid_features & CPUID_CMOV)) { 2986 goto illegal_op; 2987 } 2988 gen_update_cc_op(s); 2989 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2990 gen_helper_fcomi_ST0_FT0(tcg_env); 2991 set_cc_op(s, CC_OP_EFLAGS); 2992 break; 2993 case 0x28: /* ffree sti */ 2994 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2995 break; 2996 case 0x2a: /* fst sti */ 2997 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2998 break; 2999 case 0x2b: /* fstp sti */ 3000 case 0x0b: /* fstp1 sti, undocumented op */ 3001 case 0x3a: /* fstp8 sti, undocumented op */ 3002 case 0x3b: /* fstp9 sti, undocumented op */ 3003 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 3004 gen_helper_fpop(tcg_env); 3005 break; 3006 case 0x2c: /* fucom st(i) */ 3007 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 3008 gen_helper_fucom_ST0_FT0(tcg_env); 3009 break; 3010 case 0x2d: /* fucomp st(i) */ 3011 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 3012 gen_helper_fucom_ST0_FT0(tcg_env); 3013 gen_helper_fpop(tcg_env); 3014 break; 3015 case 0x33: /* de/3 */ 3016 switch (rm) { 3017 case 1: /* fcompp */ 3018 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 3019 gen_helper_fcom_ST0_FT0(tcg_env); 3020 gen_helper_fpop(tcg_env); 3021 gen_helper_fpop(tcg_env); 3022 break; 3023 default: 3024 return false; 3025 } 3026 break; 3027 case 0x38: /* ffreep sti, undocumented op */ 3028 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 3029 gen_helper_fpop(tcg_env); 3030 break; 3031 case 0x3c: /* df/4 */ 3032 switch (rm) { 3033 case 0: 3034 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 3035 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 3036 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3037 break; 3038 default: 3039 return false; 3040 } 3041 break; 3042 case 0x3d: /* fucomip */ 3043 if (!(s->cpuid_features & CPUID_CMOV)) { 3044 goto illegal_op; 3045 } 3046 gen_update_cc_op(s); 3047 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 3048 gen_helper_fucomi_ST0_FT0(tcg_env); 3049 gen_helper_fpop(tcg_env); 3050 set_cc_op(s, CC_OP_EFLAGS); 3051 break; 3052 case 0x3e: /* fcomip */ 3053 if (!(s->cpuid_features & CPUID_CMOV)) { 3054 goto illegal_op; 3055 } 3056 gen_update_cc_op(s); 3057 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 3058 gen_helper_fcomi_ST0_FT0(tcg_env); 3059 gen_helper_fpop(tcg_env); 3060 set_cc_op(s, CC_OP_EFLAGS); 3061 break; 3062 case 0x10 ... 0x13: /* fcmovxx */ 3063 case 0x18 ... 0x1b: 3064 { 3065 int op1; 3066 TCGLabel *l1; 3067 static const uint8_t fcmov_cc[8] = { 3068 (JCC_B << 1), 3069 (JCC_Z << 1), 3070 (JCC_BE << 1), 3071 (JCC_P << 1), 3072 }; 3073 3074 if (!(s->cpuid_features & CPUID_CMOV)) { 3075 goto illegal_op; 3076 } 3077 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 3078 l1 = gen_new_label(); 3079 gen_jcc1_noeob(s, op1, l1); 3080 gen_helper_fmov_ST0_STN(tcg_env, 3081 tcg_constant_i32(opreg)); 3082 gen_set_label(l1); 3083 } 3084 break; 3085 default: 3086 return false; 3087 } 3088 } 3089 3090 if (update_fip) { 3091 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 3092 offsetof(CPUX86State, segs[R_CS].selector)); 3093 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 3094 offsetof(CPUX86State, fpcs)); 3095 tcg_gen_st_tl(eip_cur_tl(s), 3096 tcg_env, offsetof(CPUX86State, fpip)); 3097 } 3098 return true; 3099 3100 illegal_op: 3101 gen_illegal_opcode(s); 3102 return true; 3103 } 3104 3105 static void disas_insn_old(DisasContext *s, CPUState *cpu, int b) 3106 { 3107 CPUX86State *env = cpu_env(cpu); 3108 int prefixes = s->prefix; 3109 MemOp dflag = s->dflag; 3110 int shift; 3111 MemOp ot; 3112 int modrm, reg, rm, mod, op, opreg, val; 3113 3114 /* now check op code */ 3115 switch (b) { 3116 /**************************/ 3117 /* arith & logic */ 3118 case 0x1c0: 3119 case 0x1c1: /* xadd Ev, Gv */ 3120 ot = mo_b_d(b, dflag); 3121 modrm = x86_ldub_code(env, s); 3122 reg = ((modrm >> 3) & 7) | REX_R(s); 3123 mod = (modrm >> 6) & 3; 3124 gen_op_mov_v_reg(s, ot, s->T0, reg); 3125 if (mod == 3) { 3126 rm = (modrm & 7) | REX_B(s); 3127 gen_op_mov_v_reg(s, ot, s->T1, rm); 3128 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3129 gen_op_mov_reg_v(s, ot, reg, s->T1); 3130 gen_op_mov_reg_v(s, ot, rm, s->T0); 3131 } else { 3132 gen_lea_modrm(env, s, modrm); 3133 if (s->prefix & PREFIX_LOCK) { 3134 tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0, 3135 s->mem_index, ot | MO_LE); 3136 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3137 } else { 3138 gen_op_ld_v(s, ot, s->T1, s->A0); 3139 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3140 gen_op_st_v(s, ot, s->T0, s->A0); 3141 } 3142 gen_op_mov_reg_v(s, ot, reg, s->T1); 3143 } 3144 gen_op_update2_cc(s); 3145 set_cc_op(s, CC_OP_ADDB + ot); 3146 break; 3147 case 0x1b0: 3148 case 0x1b1: /* cmpxchg Ev, Gv */ 3149 { 3150 TCGv oldv, newv, cmpv, dest; 3151 3152 ot = mo_b_d(b, dflag); 3153 modrm = x86_ldub_code(env, s); 3154 reg = ((modrm >> 3) & 7) | REX_R(s); 3155 mod = (modrm >> 6) & 3; 3156 oldv = tcg_temp_new(); 3157 newv = tcg_temp_new(); 3158 cmpv = tcg_temp_new(); 3159 gen_op_mov_v_reg(s, ot, newv, reg); 3160 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]); 3161 gen_extu(ot, cmpv); 3162 if (s->prefix & PREFIX_LOCK) { 3163 if (mod == 3) { 3164 goto illegal_op; 3165 } 3166 gen_lea_modrm(env, s, modrm); 3167 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv, 3168 s->mem_index, ot | MO_LE); 3169 } else { 3170 if (mod == 3) { 3171 rm = (modrm & 7) | REX_B(s); 3172 gen_op_mov_v_reg(s, ot, oldv, rm); 3173 gen_extu(ot, oldv); 3174 3175 /* 3176 * Unlike the memory case, where "the destination operand receives 3177 * a write cycle without regard to the result of the comparison", 3178 * rm must not be touched altogether if the write fails, including 3179 * not zero-extending it on 64-bit processors. So, precompute 3180 * the result of a successful writeback and perform the movcond 3181 * directly on cpu_regs. Also need to write accumulator first, in 3182 * case rm is part of RAX too. 3183 */ 3184 dest = gen_op_deposit_reg_v(s, ot, rm, newv, newv); 3185 tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, newv, dest); 3186 } else { 3187 gen_lea_modrm(env, s, modrm); 3188 gen_op_ld_v(s, ot, oldv, s->A0); 3189 3190 /* 3191 * Perform an unconditional store cycle like physical cpu; 3192 * must be before changing accumulator to ensure 3193 * idempotency if the store faults and the instruction 3194 * is restarted 3195 */ 3196 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv); 3197 gen_op_st_v(s, ot, newv, s->A0); 3198 } 3199 } 3200 /* 3201 * Write EAX only if the cmpxchg fails; reuse newv as the destination, 3202 * since it's dead here. 3203 */ 3204 dest = gen_op_deposit_reg_v(s, ot, R_EAX, newv, oldv); 3205 tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, dest, newv); 3206 tcg_gen_mov_tl(cpu_cc_src, oldv); 3207 tcg_gen_mov_tl(s->cc_srcT, cmpv); 3208 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv); 3209 set_cc_op(s, CC_OP_SUBB + ot); 3210 } 3211 break; 3212 case 0x1c7: /* cmpxchg8b */ 3213 modrm = x86_ldub_code(env, s); 3214 mod = (modrm >> 6) & 3; 3215 switch ((modrm >> 3) & 7) { 3216 case 1: /* CMPXCHG8, CMPXCHG16 */ 3217 if (mod == 3) { 3218 goto illegal_op; 3219 } 3220 #ifdef TARGET_X86_64 3221 if (dflag == MO_64) { 3222 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) { 3223 goto illegal_op; 3224 } 3225 gen_cmpxchg16b(s, env, modrm); 3226 break; 3227 } 3228 #endif 3229 if (!(s->cpuid_features & CPUID_CX8)) { 3230 goto illegal_op; 3231 } 3232 gen_cmpxchg8b(s, env, modrm); 3233 break; 3234 3235 case 7: /* RDSEED, RDPID with f3 prefix */ 3236 if (mod != 3 || 3237 (s->prefix & (PREFIX_LOCK | PREFIX_REPNZ))) { 3238 goto illegal_op; 3239 } 3240 if (s->prefix & PREFIX_REPZ) { 3241 if (!(s->cpuid_ext_features & CPUID_7_0_ECX_RDPID)) { 3242 goto illegal_op; 3243 } 3244 gen_helper_rdpid(s->T0, tcg_env); 3245 rm = (modrm & 7) | REX_B(s); 3246 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3247 break; 3248 } else { 3249 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) { 3250 goto illegal_op; 3251 } 3252 goto do_rdrand; 3253 } 3254 3255 case 6: /* RDRAND */ 3256 if (mod != 3 || 3257 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) || 3258 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { 3259 goto illegal_op; 3260 } 3261 do_rdrand: 3262 translator_io_start(&s->base); 3263 gen_helper_rdrand(s->T0, tcg_env); 3264 rm = (modrm & 7) | REX_B(s); 3265 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3266 set_cc_op(s, CC_OP_EFLAGS); 3267 break; 3268 3269 default: 3270 goto illegal_op; 3271 } 3272 break; 3273 3274 /**************************/ 3275 /* shifts */ 3276 case 0x1a4: /* shld imm */ 3277 op = 0; 3278 shift = 1; 3279 goto do_shiftd; 3280 case 0x1a5: /* shld cl */ 3281 op = 0; 3282 shift = 0; 3283 goto do_shiftd; 3284 case 0x1ac: /* shrd imm */ 3285 op = 1; 3286 shift = 1; 3287 goto do_shiftd; 3288 case 0x1ad: /* shrd cl */ 3289 op = 1; 3290 shift = 0; 3291 do_shiftd: 3292 ot = dflag; 3293 modrm = x86_ldub_code(env, s); 3294 mod = (modrm >> 6) & 3; 3295 rm = (modrm & 7) | REX_B(s); 3296 reg = ((modrm >> 3) & 7) | REX_R(s); 3297 if (mod != 3) { 3298 gen_lea_modrm(env, s, modrm); 3299 opreg = OR_TMP0; 3300 } else { 3301 opreg = rm; 3302 } 3303 gen_op_mov_v_reg(s, ot, s->T1, reg); 3304 3305 if (shift) { 3306 TCGv imm = tcg_constant_tl(x86_ldub_code(env, s)); 3307 gen_shiftd_rm_T1(s, ot, opreg, op, imm); 3308 } else { 3309 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]); 3310 } 3311 break; 3312 3313 /************************/ 3314 /* bit operations */ 3315 case 0x1ba: /* bt/bts/btr/btc Gv, im */ 3316 ot = dflag; 3317 modrm = x86_ldub_code(env, s); 3318 op = (modrm >> 3) & 7; 3319 mod = (modrm >> 6) & 3; 3320 rm = (modrm & 7) | REX_B(s); 3321 if (mod != 3) { 3322 s->rip_offset = 1; 3323 gen_lea_modrm(env, s, modrm); 3324 if (!(s->prefix & PREFIX_LOCK)) { 3325 gen_op_ld_v(s, ot, s->T0, s->A0); 3326 } 3327 } else { 3328 gen_op_mov_v_reg(s, ot, s->T0, rm); 3329 } 3330 /* load shift */ 3331 val = x86_ldub_code(env, s); 3332 tcg_gen_movi_tl(s->T1, val); 3333 if (op < 4) 3334 goto unknown_op; 3335 op -= 4; 3336 goto bt_op; 3337 case 0x1a3: /* bt Gv, Ev */ 3338 op = 0; 3339 goto do_btx; 3340 case 0x1ab: /* bts */ 3341 op = 1; 3342 goto do_btx; 3343 case 0x1b3: /* btr */ 3344 op = 2; 3345 goto do_btx; 3346 case 0x1bb: /* btc */ 3347 op = 3; 3348 do_btx: 3349 ot = dflag; 3350 modrm = x86_ldub_code(env, s); 3351 reg = ((modrm >> 3) & 7) | REX_R(s); 3352 mod = (modrm >> 6) & 3; 3353 rm = (modrm & 7) | REX_B(s); 3354 gen_op_mov_v_reg(s, MO_32, s->T1, reg); 3355 if (mod != 3) { 3356 AddressParts a = gen_lea_modrm_0(env, s, modrm); 3357 /* specific case: we need to add a displacement */ 3358 gen_exts(ot, s->T1); 3359 tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot); 3360 tcg_gen_shli_tl(s->tmp0, s->tmp0, ot); 3361 tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0); 3362 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 3363 if (!(s->prefix & PREFIX_LOCK)) { 3364 gen_op_ld_v(s, ot, s->T0, s->A0); 3365 } 3366 } else { 3367 gen_op_mov_v_reg(s, ot, s->T0, rm); 3368 } 3369 bt_op: 3370 tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1); 3371 tcg_gen_movi_tl(s->tmp0, 1); 3372 tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1); 3373 if (s->prefix & PREFIX_LOCK) { 3374 switch (op) { 3375 case 0: /* bt */ 3376 /* Needs no atomic ops; we suppressed the normal 3377 memory load for LOCK above so do it now. */ 3378 gen_op_ld_v(s, ot, s->T0, s->A0); 3379 break; 3380 case 1: /* bts */ 3381 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0, 3382 s->mem_index, ot | MO_LE); 3383 break; 3384 case 2: /* btr */ 3385 tcg_gen_not_tl(s->tmp0, s->tmp0); 3386 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0, 3387 s->mem_index, ot | MO_LE); 3388 break; 3389 default: 3390 case 3: /* btc */ 3391 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0, 3392 s->mem_index, ot | MO_LE); 3393 break; 3394 } 3395 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 3396 } else { 3397 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 3398 switch (op) { 3399 case 0: /* bt */ 3400 /* Data already loaded; nothing to do. */ 3401 break; 3402 case 1: /* bts */ 3403 tcg_gen_or_tl(s->T0, s->T0, s->tmp0); 3404 break; 3405 case 2: /* btr */ 3406 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0); 3407 break; 3408 default: 3409 case 3: /* btc */ 3410 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0); 3411 break; 3412 } 3413 if (op != 0) { 3414 if (mod != 3) { 3415 gen_op_st_v(s, ot, s->T0, s->A0); 3416 } else { 3417 gen_op_mov_reg_v(s, ot, rm, s->T0); 3418 } 3419 } 3420 } 3421 3422 /* Delay all CC updates until after the store above. Note that 3423 C is the result of the test, Z is unchanged, and the others 3424 are all undefined. */ 3425 switch (s->cc_op) { 3426 case CC_OP_MULB ... CC_OP_MULQ: 3427 case CC_OP_ADDB ... CC_OP_ADDQ: 3428 case CC_OP_ADCB ... CC_OP_ADCQ: 3429 case CC_OP_SUBB ... CC_OP_SUBQ: 3430 case CC_OP_SBBB ... CC_OP_SBBQ: 3431 case CC_OP_LOGICB ... CC_OP_LOGICQ: 3432 case CC_OP_INCB ... CC_OP_INCQ: 3433 case CC_OP_DECB ... CC_OP_DECQ: 3434 case CC_OP_SHLB ... CC_OP_SHLQ: 3435 case CC_OP_SARB ... CC_OP_SARQ: 3436 case CC_OP_BMILGB ... CC_OP_BMILGQ: 3437 /* Z was going to be computed from the non-zero status of CC_DST. 3438 We can get that same Z value (and the new C value) by leaving 3439 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the 3440 same width. */ 3441 tcg_gen_mov_tl(cpu_cc_src, s->tmp4); 3442 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB); 3443 break; 3444 default: 3445 /* Otherwise, generate EFLAGS and replace the C bit. */ 3446 gen_compute_eflags(s); 3447 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4, 3448 ctz32(CC_C), 1); 3449 break; 3450 } 3451 break; 3452 case 0x1bc: /* bsf / tzcnt */ 3453 case 0x1bd: /* bsr / lzcnt */ 3454 ot = dflag; 3455 modrm = x86_ldub_code(env, s); 3456 reg = ((modrm >> 3) & 7) | REX_R(s); 3457 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3458 gen_extu(ot, s->T0); 3459 3460 /* Note that lzcnt and tzcnt are in different extensions. */ 3461 if ((prefixes & PREFIX_REPZ) 3462 && (b & 1 3463 ? s->cpuid_ext3_features & CPUID_EXT3_ABM 3464 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) { 3465 int size = 8 << ot; 3466 /* For lzcnt/tzcnt, C bit is defined related to the input. */ 3467 tcg_gen_mov_tl(cpu_cc_src, s->T0); 3468 if (b & 1) { 3469 /* For lzcnt, reduce the target_ulong result by the 3470 number of zeros that we expect to find at the top. */ 3471 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS); 3472 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size); 3473 } else { 3474 /* For tzcnt, a zero input must return the operand size. */ 3475 tcg_gen_ctzi_tl(s->T0, s->T0, size); 3476 } 3477 /* For lzcnt/tzcnt, Z bit is defined related to the result. */ 3478 gen_op_update1_cc(s); 3479 set_cc_op(s, CC_OP_BMILGB + ot); 3480 } else { 3481 /* For bsr/bsf, only the Z bit is defined and it is related 3482 to the input and not the result. */ 3483 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3484 set_cc_op(s, CC_OP_LOGICB + ot); 3485 3486 /* ??? The manual says that the output is undefined when the 3487 input is zero, but real hardware leaves it unchanged, and 3488 real programs appear to depend on that. Accomplish this 3489 by passing the output as the value to return upon zero. */ 3490 if (b & 1) { 3491 /* For bsr, return the bit index of the first 1 bit, 3492 not the count of leading zeros. */ 3493 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1); 3494 tcg_gen_clz_tl(s->T0, s->T0, s->T1); 3495 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1); 3496 } else { 3497 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]); 3498 } 3499 } 3500 gen_op_mov_reg_v(s, ot, reg, s->T0); 3501 break; 3502 case 0x130: /* wrmsr */ 3503 case 0x132: /* rdmsr */ 3504 if (check_cpl0(s)) { 3505 gen_update_cc_op(s); 3506 gen_update_eip_cur(s); 3507 if (b & 2) { 3508 gen_helper_rdmsr(tcg_env); 3509 } else { 3510 gen_helper_wrmsr(tcg_env); 3511 s->base.is_jmp = DISAS_EOB_NEXT; 3512 } 3513 } 3514 break; 3515 case 0x131: /* rdtsc */ 3516 gen_update_cc_op(s); 3517 gen_update_eip_cur(s); 3518 translator_io_start(&s->base); 3519 gen_helper_rdtsc(tcg_env); 3520 break; 3521 case 0x133: /* rdpmc */ 3522 gen_update_cc_op(s); 3523 gen_update_eip_cur(s); 3524 gen_helper_rdpmc(tcg_env); 3525 s->base.is_jmp = DISAS_NORETURN; 3526 break; 3527 case 0x134: /* sysenter */ 3528 /* For AMD SYSENTER is not valid in long mode */ 3529 if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) { 3530 goto illegal_op; 3531 } 3532 if (!PE(s)) { 3533 gen_exception_gpf(s); 3534 } else { 3535 gen_helper_sysenter(tcg_env); 3536 s->base.is_jmp = DISAS_EOB_ONLY; 3537 } 3538 break; 3539 case 0x135: /* sysexit */ 3540 /* For AMD SYSEXIT is not valid in long mode */ 3541 if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) { 3542 goto illegal_op; 3543 } 3544 if (!PE(s) || CPL(s) != 0) { 3545 gen_exception_gpf(s); 3546 } else { 3547 gen_helper_sysexit(tcg_env, tcg_constant_i32(dflag - 1)); 3548 s->base.is_jmp = DISAS_EOB_ONLY; 3549 } 3550 break; 3551 case 0x105: /* syscall */ 3552 /* For Intel SYSCALL is only valid in long mode */ 3553 if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) { 3554 goto illegal_op; 3555 } 3556 gen_update_cc_op(s); 3557 gen_update_eip_cur(s); 3558 gen_helper_syscall(tcg_env, cur_insn_len_i32(s)); 3559 /* TF handling for the syscall insn is different. The TF bit is checked 3560 after the syscall insn completes. This allows #DB to not be 3561 generated after one has entered CPL0 if TF is set in FMASK. */ 3562 gen_eob_syscall(s); 3563 break; 3564 case 0x107: /* sysret */ 3565 /* For Intel SYSRET is only valid in long mode */ 3566 if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) { 3567 goto illegal_op; 3568 } 3569 if (!PE(s) || CPL(s) != 0) { 3570 gen_exception_gpf(s); 3571 } else { 3572 gen_helper_sysret(tcg_env, tcg_constant_i32(dflag - 1)); 3573 /* condition codes are modified only in long mode */ 3574 if (LMA(s)) { 3575 set_cc_op(s, CC_OP_EFLAGS); 3576 } 3577 /* TF handling for the sysret insn is different. The TF bit is 3578 checked after the sysret insn completes. This allows #DB to be 3579 generated "as if" the syscall insn in userspace has just 3580 completed. */ 3581 gen_eob_syscall(s); 3582 } 3583 break; 3584 case 0x1a2: /* cpuid */ 3585 gen_update_cc_op(s); 3586 gen_update_eip_cur(s); 3587 gen_helper_cpuid(tcg_env); 3588 break; 3589 case 0x100: 3590 modrm = x86_ldub_code(env, s); 3591 mod = (modrm >> 6) & 3; 3592 op = (modrm >> 3) & 7; 3593 switch(op) { 3594 case 0: /* sldt */ 3595 if (!PE(s) || VM86(s)) 3596 goto illegal_op; 3597 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3598 break; 3599 } 3600 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ); 3601 tcg_gen_ld32u_tl(s->T0, tcg_env, 3602 offsetof(CPUX86State, ldt.selector)); 3603 ot = mod == 3 ? dflag : MO_16; 3604 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 3605 break; 3606 case 2: /* lldt */ 3607 if (!PE(s) || VM86(s)) 3608 goto illegal_op; 3609 if (check_cpl0(s)) { 3610 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE); 3611 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3612 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3613 gen_helper_lldt(tcg_env, s->tmp2_i32); 3614 } 3615 break; 3616 case 1: /* str */ 3617 if (!PE(s) || VM86(s)) 3618 goto illegal_op; 3619 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3620 break; 3621 } 3622 gen_svm_check_intercept(s, SVM_EXIT_TR_READ); 3623 tcg_gen_ld32u_tl(s->T0, tcg_env, 3624 offsetof(CPUX86State, tr.selector)); 3625 ot = mod == 3 ? dflag : MO_16; 3626 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 3627 break; 3628 case 3: /* ltr */ 3629 if (!PE(s) || VM86(s)) 3630 goto illegal_op; 3631 if (check_cpl0(s)) { 3632 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE); 3633 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3634 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3635 gen_helper_ltr(tcg_env, s->tmp2_i32); 3636 } 3637 break; 3638 case 4: /* verr */ 3639 case 5: /* verw */ 3640 if (!PE(s) || VM86(s)) 3641 goto illegal_op; 3642 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3643 gen_update_cc_op(s); 3644 if (op == 4) { 3645 gen_helper_verr(tcg_env, s->T0); 3646 } else { 3647 gen_helper_verw(tcg_env, s->T0); 3648 } 3649 set_cc_op(s, CC_OP_EFLAGS); 3650 break; 3651 default: 3652 goto unknown_op; 3653 } 3654 break; 3655 3656 case 0x101: 3657 modrm = x86_ldub_code(env, s); 3658 switch (modrm) { 3659 CASE_MODRM_MEM_OP(0): /* sgdt */ 3660 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3661 break; 3662 } 3663 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ); 3664 gen_lea_modrm(env, s, modrm); 3665 tcg_gen_ld32u_tl(s->T0, 3666 tcg_env, offsetof(CPUX86State, gdt.limit)); 3667 gen_op_st_v(s, MO_16, s->T0, s->A0); 3668 gen_add_A0_im(s, 2); 3669 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3670 /* 3671 * NB: Despite a confusing description in Intel CPU documentation, 3672 * all 32-bits are written regardless of operand size. 3673 */ 3674 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3675 break; 3676 3677 case 0xc8: /* monitor */ 3678 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3679 goto illegal_op; 3680 } 3681 gen_update_cc_op(s); 3682 gen_update_eip_cur(s); 3683 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 3684 gen_add_A0_ds_seg(s); 3685 gen_helper_monitor(tcg_env, s->A0); 3686 break; 3687 3688 case 0xc9: /* mwait */ 3689 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3690 goto illegal_op; 3691 } 3692 gen_update_cc_op(s); 3693 gen_update_eip_cur(s); 3694 gen_helper_mwait(tcg_env, cur_insn_len_i32(s)); 3695 s->base.is_jmp = DISAS_NORETURN; 3696 break; 3697 3698 case 0xca: /* clac */ 3699 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3700 || CPL(s) != 0) { 3701 goto illegal_op; 3702 } 3703 gen_reset_eflags(s, AC_MASK); 3704 s->base.is_jmp = DISAS_EOB_NEXT; 3705 break; 3706 3707 case 0xcb: /* stac */ 3708 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3709 || CPL(s) != 0) { 3710 goto illegal_op; 3711 } 3712 gen_set_eflags(s, AC_MASK); 3713 s->base.is_jmp = DISAS_EOB_NEXT; 3714 break; 3715 3716 CASE_MODRM_MEM_OP(1): /* sidt */ 3717 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3718 break; 3719 } 3720 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ); 3721 gen_lea_modrm(env, s, modrm); 3722 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.limit)); 3723 gen_op_st_v(s, MO_16, s->T0, s->A0); 3724 gen_add_A0_im(s, 2); 3725 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3726 /* 3727 * NB: Despite a confusing description in Intel CPU documentation, 3728 * all 32-bits are written regardless of operand size. 3729 */ 3730 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3731 break; 3732 3733 case 0xd0: /* xgetbv */ 3734 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3735 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3736 | PREFIX_REPZ | PREFIX_REPNZ))) { 3737 goto illegal_op; 3738 } 3739 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3740 gen_helper_xgetbv(s->tmp1_i64, tcg_env, s->tmp2_i32); 3741 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3742 break; 3743 3744 case 0xd1: /* xsetbv */ 3745 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3746 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3747 | PREFIX_REPZ | PREFIX_REPNZ))) { 3748 goto illegal_op; 3749 } 3750 gen_svm_check_intercept(s, SVM_EXIT_XSETBV); 3751 if (!check_cpl0(s)) { 3752 break; 3753 } 3754 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3755 cpu_regs[R_EDX]); 3756 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3757 gen_helper_xsetbv(tcg_env, s->tmp2_i32, s->tmp1_i64); 3758 /* End TB because translation flags may change. */ 3759 s->base.is_jmp = DISAS_EOB_NEXT; 3760 break; 3761 3762 case 0xd8: /* VMRUN */ 3763 if (!SVME(s) || !PE(s)) { 3764 goto illegal_op; 3765 } 3766 if (!check_cpl0(s)) { 3767 break; 3768 } 3769 gen_update_cc_op(s); 3770 gen_update_eip_cur(s); 3771 gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1), 3772 cur_insn_len_i32(s)); 3773 tcg_gen_exit_tb(NULL, 0); 3774 s->base.is_jmp = DISAS_NORETURN; 3775 break; 3776 3777 case 0xd9: /* VMMCALL */ 3778 if (!SVME(s)) { 3779 goto illegal_op; 3780 } 3781 gen_update_cc_op(s); 3782 gen_update_eip_cur(s); 3783 gen_helper_vmmcall(tcg_env); 3784 break; 3785 3786 case 0xda: /* VMLOAD */ 3787 if (!SVME(s) || !PE(s)) { 3788 goto illegal_op; 3789 } 3790 if (!check_cpl0(s)) { 3791 break; 3792 } 3793 gen_update_cc_op(s); 3794 gen_update_eip_cur(s); 3795 gen_helper_vmload(tcg_env, tcg_constant_i32(s->aflag - 1)); 3796 break; 3797 3798 case 0xdb: /* VMSAVE */ 3799 if (!SVME(s) || !PE(s)) { 3800 goto illegal_op; 3801 } 3802 if (!check_cpl0(s)) { 3803 break; 3804 } 3805 gen_update_cc_op(s); 3806 gen_update_eip_cur(s); 3807 gen_helper_vmsave(tcg_env, tcg_constant_i32(s->aflag - 1)); 3808 break; 3809 3810 case 0xdc: /* STGI */ 3811 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3812 || !PE(s)) { 3813 goto illegal_op; 3814 } 3815 if (!check_cpl0(s)) { 3816 break; 3817 } 3818 gen_update_cc_op(s); 3819 gen_helper_stgi(tcg_env); 3820 s->base.is_jmp = DISAS_EOB_NEXT; 3821 break; 3822 3823 case 0xdd: /* CLGI */ 3824 if (!SVME(s) || !PE(s)) { 3825 goto illegal_op; 3826 } 3827 if (!check_cpl0(s)) { 3828 break; 3829 } 3830 gen_update_cc_op(s); 3831 gen_update_eip_cur(s); 3832 gen_helper_clgi(tcg_env); 3833 break; 3834 3835 case 0xde: /* SKINIT */ 3836 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3837 || !PE(s)) { 3838 goto illegal_op; 3839 } 3840 gen_svm_check_intercept(s, SVM_EXIT_SKINIT); 3841 /* If not intercepted, not implemented -- raise #UD. */ 3842 goto illegal_op; 3843 3844 case 0xdf: /* INVLPGA */ 3845 if (!SVME(s) || !PE(s)) { 3846 goto illegal_op; 3847 } 3848 if (!check_cpl0(s)) { 3849 break; 3850 } 3851 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA); 3852 if (s->aflag == MO_64) { 3853 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 3854 } else { 3855 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]); 3856 } 3857 gen_helper_flush_page(tcg_env, s->A0); 3858 s->base.is_jmp = DISAS_EOB_NEXT; 3859 break; 3860 3861 CASE_MODRM_MEM_OP(2): /* lgdt */ 3862 if (!check_cpl0(s)) { 3863 break; 3864 } 3865 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE); 3866 gen_lea_modrm(env, s, modrm); 3867 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3868 gen_add_A0_im(s, 2); 3869 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3870 if (dflag == MO_16) { 3871 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3872 } 3873 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3874 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, gdt.limit)); 3875 break; 3876 3877 CASE_MODRM_MEM_OP(3): /* lidt */ 3878 if (!check_cpl0(s)) { 3879 break; 3880 } 3881 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE); 3882 gen_lea_modrm(env, s, modrm); 3883 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3884 gen_add_A0_im(s, 2); 3885 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3886 if (dflag == MO_16) { 3887 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3888 } 3889 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3890 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, idt.limit)); 3891 break; 3892 3893 CASE_MODRM_OP(4): /* smsw */ 3894 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3895 break; 3896 } 3897 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0); 3898 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, cr[0])); 3899 /* 3900 * In 32-bit mode, the higher 16 bits of the destination 3901 * register are undefined. In practice CR0[31:0] is stored 3902 * just like in 64-bit mode. 3903 */ 3904 mod = (modrm >> 6) & 3; 3905 ot = (mod != 3 ? MO_16 : s->dflag); 3906 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 3907 break; 3908 case 0xee: /* rdpkru */ 3909 if (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3910 | PREFIX_REPZ | PREFIX_REPNZ)) { 3911 goto illegal_op; 3912 } 3913 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3914 gen_helper_rdpkru(s->tmp1_i64, tcg_env, s->tmp2_i32); 3915 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3916 break; 3917 case 0xef: /* wrpkru */ 3918 if (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3919 | PREFIX_REPZ | PREFIX_REPNZ)) { 3920 goto illegal_op; 3921 } 3922 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3923 cpu_regs[R_EDX]); 3924 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3925 gen_helper_wrpkru(tcg_env, s->tmp2_i32, s->tmp1_i64); 3926 break; 3927 3928 CASE_MODRM_OP(6): /* lmsw */ 3929 if (!check_cpl0(s)) { 3930 break; 3931 } 3932 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 3933 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3934 /* 3935 * Only the 4 lower bits of CR0 are modified. 3936 * PE cannot be set to zero if already set to one. 3937 */ 3938 tcg_gen_ld_tl(s->T1, tcg_env, offsetof(CPUX86State, cr[0])); 3939 tcg_gen_andi_tl(s->T0, s->T0, 0xf); 3940 tcg_gen_andi_tl(s->T1, s->T1, ~0xe); 3941 tcg_gen_or_tl(s->T0, s->T0, s->T1); 3942 gen_helper_write_crN(tcg_env, tcg_constant_i32(0), s->T0); 3943 s->base.is_jmp = DISAS_EOB_NEXT; 3944 break; 3945 3946 CASE_MODRM_MEM_OP(7): /* invlpg */ 3947 if (!check_cpl0(s)) { 3948 break; 3949 } 3950 gen_svm_check_intercept(s, SVM_EXIT_INVLPG); 3951 gen_lea_modrm(env, s, modrm); 3952 gen_helper_flush_page(tcg_env, s->A0); 3953 s->base.is_jmp = DISAS_EOB_NEXT; 3954 break; 3955 3956 case 0xf8: /* swapgs */ 3957 #ifdef TARGET_X86_64 3958 if (CODE64(s)) { 3959 if (check_cpl0(s)) { 3960 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]); 3961 tcg_gen_ld_tl(cpu_seg_base[R_GS], tcg_env, 3962 offsetof(CPUX86State, kernelgsbase)); 3963 tcg_gen_st_tl(s->T0, tcg_env, 3964 offsetof(CPUX86State, kernelgsbase)); 3965 } 3966 break; 3967 } 3968 #endif 3969 goto illegal_op; 3970 3971 case 0xf9: /* rdtscp */ 3972 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) { 3973 goto illegal_op; 3974 } 3975 gen_update_cc_op(s); 3976 gen_update_eip_cur(s); 3977 translator_io_start(&s->base); 3978 gen_helper_rdtsc(tcg_env); 3979 gen_helper_rdpid(s->T0, tcg_env); 3980 gen_op_mov_reg_v(s, dflag, R_ECX, s->T0); 3981 break; 3982 3983 default: 3984 goto unknown_op; 3985 } 3986 break; 3987 3988 case 0x108: /* invd */ 3989 case 0x109: /* wbinvd; wbnoinvd with REPZ prefix */ 3990 if (check_cpl0(s)) { 3991 gen_svm_check_intercept(s, (b & 1) ? SVM_EXIT_WBINVD : SVM_EXIT_INVD); 3992 /* nothing to do */ 3993 } 3994 break; 3995 case 0x102: /* lar */ 3996 case 0x103: /* lsl */ 3997 { 3998 TCGLabel *label1; 3999 TCGv t0; 4000 if (!PE(s) || VM86(s)) 4001 goto illegal_op; 4002 ot = dflag != MO_16 ? MO_32 : MO_16; 4003 modrm = x86_ldub_code(env, s); 4004 reg = ((modrm >> 3) & 7) | REX_R(s); 4005 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 4006 t0 = tcg_temp_new(); 4007 gen_update_cc_op(s); 4008 if (b == 0x102) { 4009 gen_helper_lar(t0, tcg_env, s->T0); 4010 } else { 4011 gen_helper_lsl(t0, tcg_env, s->T0); 4012 } 4013 tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z); 4014 label1 = gen_new_label(); 4015 tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1); 4016 gen_op_mov_reg_v(s, ot, reg, t0); 4017 gen_set_label(label1); 4018 set_cc_op(s, CC_OP_EFLAGS); 4019 } 4020 break; 4021 case 0x11a: 4022 modrm = x86_ldub_code(env, s); 4023 if (s->flags & HF_MPX_EN_MASK) { 4024 mod = (modrm >> 6) & 3; 4025 reg = ((modrm >> 3) & 7) | REX_R(s); 4026 if (prefixes & PREFIX_REPZ) { 4027 /* bndcl */ 4028 if (reg >= 4 4029 || (prefixes & PREFIX_LOCK) 4030 || s->aflag == MO_16) { 4031 goto illegal_op; 4032 } 4033 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]); 4034 } else if (prefixes & PREFIX_REPNZ) { 4035 /* bndcu */ 4036 if (reg >= 4 4037 || (prefixes & PREFIX_LOCK) 4038 || s->aflag == MO_16) { 4039 goto illegal_op; 4040 } 4041 TCGv_i64 notu = tcg_temp_new_i64(); 4042 tcg_gen_not_i64(notu, cpu_bndu[reg]); 4043 gen_bndck(env, s, modrm, TCG_COND_GTU, notu); 4044 } else if (prefixes & PREFIX_DATA) { 4045 /* bndmov -- from reg/mem */ 4046 if (reg >= 4 || s->aflag == MO_16) { 4047 goto illegal_op; 4048 } 4049 if (mod == 3) { 4050 int reg2 = (modrm & 7) | REX_B(s); 4051 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 4052 goto illegal_op; 4053 } 4054 if (s->flags & HF_MPX_IU_MASK) { 4055 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]); 4056 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]); 4057 } 4058 } else { 4059 gen_lea_modrm(env, s, modrm); 4060 if (CODE64(s)) { 4061 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 4062 s->mem_index, MO_LEUQ); 4063 tcg_gen_addi_tl(s->A0, s->A0, 8); 4064 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 4065 s->mem_index, MO_LEUQ); 4066 } else { 4067 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 4068 s->mem_index, MO_LEUL); 4069 tcg_gen_addi_tl(s->A0, s->A0, 4); 4070 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 4071 s->mem_index, MO_LEUL); 4072 } 4073 /* bnd registers are now in-use */ 4074 gen_set_hflag(s, HF_MPX_IU_MASK); 4075 } 4076 } else if (mod != 3) { 4077 /* bndldx */ 4078 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4079 if (reg >= 4 4080 || (prefixes & PREFIX_LOCK) 4081 || s->aflag == MO_16 4082 || a.base < -1) { 4083 goto illegal_op; 4084 } 4085 if (a.base >= 0) { 4086 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 4087 } else { 4088 tcg_gen_movi_tl(s->A0, 0); 4089 } 4090 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 4091 if (a.index >= 0) { 4092 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 4093 } else { 4094 tcg_gen_movi_tl(s->T0, 0); 4095 } 4096 if (CODE64(s)) { 4097 gen_helper_bndldx64(cpu_bndl[reg], tcg_env, s->A0, s->T0); 4098 tcg_gen_ld_i64(cpu_bndu[reg], tcg_env, 4099 offsetof(CPUX86State, mmx_t0.MMX_Q(0))); 4100 } else { 4101 gen_helper_bndldx32(cpu_bndu[reg], tcg_env, s->A0, s->T0); 4102 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]); 4103 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32); 4104 } 4105 gen_set_hflag(s, HF_MPX_IU_MASK); 4106 } 4107 } 4108 gen_nop_modrm(env, s, modrm); 4109 break; 4110 case 0x11b: 4111 modrm = x86_ldub_code(env, s); 4112 if (s->flags & HF_MPX_EN_MASK) { 4113 mod = (modrm >> 6) & 3; 4114 reg = ((modrm >> 3) & 7) | REX_R(s); 4115 if (mod != 3 && (prefixes & PREFIX_REPZ)) { 4116 /* bndmk */ 4117 if (reg >= 4 4118 || (prefixes & PREFIX_LOCK) 4119 || s->aflag == MO_16) { 4120 goto illegal_op; 4121 } 4122 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4123 if (a.base >= 0) { 4124 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]); 4125 if (!CODE64(s)) { 4126 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]); 4127 } 4128 } else if (a.base == -1) { 4129 /* no base register has lower bound of 0 */ 4130 tcg_gen_movi_i64(cpu_bndl[reg], 0); 4131 } else { 4132 /* rip-relative generates #ud */ 4133 goto illegal_op; 4134 } 4135 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false)); 4136 if (!CODE64(s)) { 4137 tcg_gen_ext32u_tl(s->A0, s->A0); 4138 } 4139 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0); 4140 /* bnd registers are now in-use */ 4141 gen_set_hflag(s, HF_MPX_IU_MASK); 4142 break; 4143 } else if (prefixes & PREFIX_REPNZ) { 4144 /* bndcn */ 4145 if (reg >= 4 4146 || (prefixes & PREFIX_LOCK) 4147 || s->aflag == MO_16) { 4148 goto illegal_op; 4149 } 4150 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]); 4151 } else if (prefixes & PREFIX_DATA) { 4152 /* bndmov -- to reg/mem */ 4153 if (reg >= 4 || s->aflag == MO_16) { 4154 goto illegal_op; 4155 } 4156 if (mod == 3) { 4157 int reg2 = (modrm & 7) | REX_B(s); 4158 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 4159 goto illegal_op; 4160 } 4161 if (s->flags & HF_MPX_IU_MASK) { 4162 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]); 4163 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]); 4164 } 4165 } else { 4166 gen_lea_modrm(env, s, modrm); 4167 if (CODE64(s)) { 4168 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 4169 s->mem_index, MO_LEUQ); 4170 tcg_gen_addi_tl(s->A0, s->A0, 8); 4171 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 4172 s->mem_index, MO_LEUQ); 4173 } else { 4174 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 4175 s->mem_index, MO_LEUL); 4176 tcg_gen_addi_tl(s->A0, s->A0, 4); 4177 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 4178 s->mem_index, MO_LEUL); 4179 } 4180 } 4181 } else if (mod != 3) { 4182 /* bndstx */ 4183 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4184 if (reg >= 4 4185 || (prefixes & PREFIX_LOCK) 4186 || s->aflag == MO_16 4187 || a.base < -1) { 4188 goto illegal_op; 4189 } 4190 if (a.base >= 0) { 4191 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 4192 } else { 4193 tcg_gen_movi_tl(s->A0, 0); 4194 } 4195 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 4196 if (a.index >= 0) { 4197 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 4198 } else { 4199 tcg_gen_movi_tl(s->T0, 0); 4200 } 4201 if (CODE64(s)) { 4202 gen_helper_bndstx64(tcg_env, s->A0, s->T0, 4203 cpu_bndl[reg], cpu_bndu[reg]); 4204 } else { 4205 gen_helper_bndstx32(tcg_env, s->A0, s->T0, 4206 cpu_bndl[reg], cpu_bndu[reg]); 4207 } 4208 } 4209 } 4210 gen_nop_modrm(env, s, modrm); 4211 break; 4212 4213 case 0x120: /* mov reg, crN */ 4214 case 0x122: /* mov crN, reg */ 4215 if (!check_cpl0(s)) { 4216 break; 4217 } 4218 modrm = x86_ldub_code(env, s); 4219 /* 4220 * Ignore the mod bits (assume (modrm&0xc0)==0xc0). 4221 * AMD documentation (24594.pdf) and testing of Intel 386 and 486 4222 * processors all show that the mod bits are assumed to be 1's, 4223 * regardless of actual values. 4224 */ 4225 rm = (modrm & 7) | REX_B(s); 4226 reg = ((modrm >> 3) & 7) | REX_R(s); 4227 switch (reg) { 4228 case 0: 4229 if ((prefixes & PREFIX_LOCK) && 4230 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) { 4231 reg = 8; 4232 } 4233 break; 4234 case 2: 4235 case 3: 4236 case 4: 4237 case 8: 4238 break; 4239 default: 4240 goto unknown_op; 4241 } 4242 ot = (CODE64(s) ? MO_64 : MO_32); 4243 4244 translator_io_start(&s->base); 4245 if (b & 2) { 4246 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg); 4247 gen_op_mov_v_reg(s, ot, s->T0, rm); 4248 gen_helper_write_crN(tcg_env, tcg_constant_i32(reg), s->T0); 4249 s->base.is_jmp = DISAS_EOB_NEXT; 4250 } else { 4251 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg); 4252 gen_helper_read_crN(s->T0, tcg_env, tcg_constant_i32(reg)); 4253 gen_op_mov_reg_v(s, ot, rm, s->T0); 4254 } 4255 break; 4256 4257 case 0x121: /* mov reg, drN */ 4258 case 0x123: /* mov drN, reg */ 4259 if (check_cpl0(s)) { 4260 modrm = x86_ldub_code(env, s); 4261 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). 4262 * AMD documentation (24594.pdf) and testing of 4263 * intel 386 and 486 processors all show that the mod bits 4264 * are assumed to be 1's, regardless of actual values. 4265 */ 4266 rm = (modrm & 7) | REX_B(s); 4267 reg = ((modrm >> 3) & 7) | REX_R(s); 4268 if (CODE64(s)) 4269 ot = MO_64; 4270 else 4271 ot = MO_32; 4272 if (reg >= 8) { 4273 goto illegal_op; 4274 } 4275 if (b & 2) { 4276 gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg); 4277 gen_op_mov_v_reg(s, ot, s->T0, rm); 4278 tcg_gen_movi_i32(s->tmp2_i32, reg); 4279 gen_helper_set_dr(tcg_env, s->tmp2_i32, s->T0); 4280 s->base.is_jmp = DISAS_EOB_NEXT; 4281 } else { 4282 gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg); 4283 tcg_gen_movi_i32(s->tmp2_i32, reg); 4284 gen_helper_get_dr(s->T0, tcg_env, s->tmp2_i32); 4285 gen_op_mov_reg_v(s, ot, rm, s->T0); 4286 } 4287 } 4288 break; 4289 case 0x106: /* clts */ 4290 if (check_cpl0(s)) { 4291 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 4292 gen_helper_clts(tcg_env); 4293 /* abort block because static cpu state changed */ 4294 s->base.is_jmp = DISAS_EOB_NEXT; 4295 } 4296 break; 4297 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */ 4298 case 0x1ae: 4299 modrm = x86_ldub_code(env, s); 4300 switch (modrm) { 4301 CASE_MODRM_MEM_OP(0): /* fxsave */ 4302 if (!(s->cpuid_features & CPUID_FXSR) 4303 || (prefixes & PREFIX_LOCK)) { 4304 goto illegal_op; 4305 } 4306 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 4307 gen_exception(s, EXCP07_PREX); 4308 break; 4309 } 4310 gen_lea_modrm(env, s, modrm); 4311 gen_helper_fxsave(tcg_env, s->A0); 4312 break; 4313 4314 CASE_MODRM_MEM_OP(1): /* fxrstor */ 4315 if (!(s->cpuid_features & CPUID_FXSR) 4316 || (prefixes & PREFIX_LOCK)) { 4317 goto illegal_op; 4318 } 4319 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 4320 gen_exception(s, EXCP07_PREX); 4321 break; 4322 } 4323 gen_lea_modrm(env, s, modrm); 4324 gen_helper_fxrstor(tcg_env, s->A0); 4325 break; 4326 4327 CASE_MODRM_MEM_OP(2): /* ldmxcsr */ 4328 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 4329 goto illegal_op; 4330 } 4331 if (s->flags & HF_TS_MASK) { 4332 gen_exception(s, EXCP07_PREX); 4333 break; 4334 } 4335 gen_lea_modrm(env, s, modrm); 4336 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL); 4337 gen_helper_ldmxcsr(tcg_env, s->tmp2_i32); 4338 break; 4339 4340 CASE_MODRM_MEM_OP(3): /* stmxcsr */ 4341 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 4342 goto illegal_op; 4343 } 4344 if (s->flags & HF_TS_MASK) { 4345 gen_exception(s, EXCP07_PREX); 4346 break; 4347 } 4348 gen_helper_update_mxcsr(tcg_env); 4349 gen_lea_modrm(env, s, modrm); 4350 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, mxcsr)); 4351 gen_op_st_v(s, MO_32, s->T0, s->A0); 4352 break; 4353 4354 CASE_MODRM_MEM_OP(4): /* xsave */ 4355 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 4356 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 4357 | PREFIX_REPZ | PREFIX_REPNZ))) { 4358 goto illegal_op; 4359 } 4360 gen_lea_modrm(env, s, modrm); 4361 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 4362 cpu_regs[R_EDX]); 4363 gen_helper_xsave(tcg_env, s->A0, s->tmp1_i64); 4364 break; 4365 4366 CASE_MODRM_MEM_OP(5): /* xrstor */ 4367 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 4368 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 4369 | PREFIX_REPZ | PREFIX_REPNZ))) { 4370 goto illegal_op; 4371 } 4372 gen_lea_modrm(env, s, modrm); 4373 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 4374 cpu_regs[R_EDX]); 4375 gen_helper_xrstor(tcg_env, s->A0, s->tmp1_i64); 4376 /* XRSTOR is how MPX is enabled, which changes how 4377 we translate. Thus we need to end the TB. */ 4378 s->base.is_jmp = DISAS_EOB_NEXT; 4379 break; 4380 4381 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */ 4382 if (prefixes & PREFIX_LOCK) { 4383 goto illegal_op; 4384 } 4385 if (prefixes & PREFIX_DATA) { 4386 /* clwb */ 4387 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) { 4388 goto illegal_op; 4389 } 4390 gen_nop_modrm(env, s, modrm); 4391 } else { 4392 /* xsaveopt */ 4393 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 4394 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0 4395 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) { 4396 goto illegal_op; 4397 } 4398 gen_lea_modrm(env, s, modrm); 4399 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 4400 cpu_regs[R_EDX]); 4401 gen_helper_xsaveopt(tcg_env, s->A0, s->tmp1_i64); 4402 } 4403 break; 4404 4405 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */ 4406 if (prefixes & PREFIX_LOCK) { 4407 goto illegal_op; 4408 } 4409 if (prefixes & PREFIX_DATA) { 4410 /* clflushopt */ 4411 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) { 4412 goto illegal_op; 4413 } 4414 } else { 4415 /* clflush */ 4416 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) 4417 || !(s->cpuid_features & CPUID_CLFLUSH)) { 4418 goto illegal_op; 4419 } 4420 } 4421 gen_nop_modrm(env, s, modrm); 4422 break; 4423 4424 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */ 4425 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */ 4426 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */ 4427 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */ 4428 if (CODE64(s) 4429 && (prefixes & PREFIX_REPZ) 4430 && !(prefixes & PREFIX_LOCK) 4431 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) { 4432 TCGv base, treg, src, dst; 4433 4434 /* Preserve hflags bits by testing CR4 at runtime. */ 4435 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK); 4436 gen_helper_cr4_testbit(tcg_env, s->tmp2_i32); 4437 4438 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS]; 4439 treg = cpu_regs[(modrm & 7) | REX_B(s)]; 4440 4441 if (modrm & 0x10) { 4442 /* wr*base */ 4443 dst = base, src = treg; 4444 } else { 4445 /* rd*base */ 4446 dst = treg, src = base; 4447 } 4448 4449 if (s->dflag == MO_32) { 4450 tcg_gen_ext32u_tl(dst, src); 4451 } else { 4452 tcg_gen_mov_tl(dst, src); 4453 } 4454 break; 4455 } 4456 goto unknown_op; 4457 4458 case 0xf8 ... 0xff: /* sfence */ 4459 if (!(s->cpuid_features & CPUID_SSE) 4460 || (prefixes & PREFIX_LOCK)) { 4461 goto illegal_op; 4462 } 4463 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC); 4464 break; 4465 case 0xe8 ... 0xef: /* lfence */ 4466 if (!(s->cpuid_features & CPUID_SSE) 4467 || (prefixes & PREFIX_LOCK)) { 4468 goto illegal_op; 4469 } 4470 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC); 4471 break; 4472 case 0xf0 ... 0xf7: /* mfence */ 4473 if (!(s->cpuid_features & CPUID_SSE2) 4474 || (prefixes & PREFIX_LOCK)) { 4475 goto illegal_op; 4476 } 4477 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 4478 break; 4479 4480 default: 4481 goto unknown_op; 4482 } 4483 break; 4484 4485 case 0x1aa: /* rsm */ 4486 gen_svm_check_intercept(s, SVM_EXIT_RSM); 4487 if (!(s->flags & HF_SMM_MASK)) 4488 goto illegal_op; 4489 #ifdef CONFIG_USER_ONLY 4490 /* we should not be in SMM mode */ 4491 g_assert_not_reached(); 4492 #else 4493 gen_update_cc_op(s); 4494 gen_update_eip_next(s); 4495 gen_helper_rsm(tcg_env); 4496 #endif /* CONFIG_USER_ONLY */ 4497 s->base.is_jmp = DISAS_EOB_ONLY; 4498 break; 4499 case 0x1b8: /* SSE4.2 popcnt */ 4500 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) != 4501 PREFIX_REPZ) 4502 goto illegal_op; 4503 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT)) 4504 goto illegal_op; 4505 4506 modrm = x86_ldub_code(env, s); 4507 reg = ((modrm >> 3) & 7) | REX_R(s); 4508 4509 ot = dflag; 4510 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 4511 gen_extu(ot, s->T0); 4512 tcg_gen_mov_tl(cpu_cc_src, s->T0); 4513 tcg_gen_ctpop_tl(s->T0, s->T0); 4514 gen_op_mov_reg_v(s, ot, reg, s->T0); 4515 4516 set_cc_op(s, CC_OP_POPCNT); 4517 break; 4518 default: 4519 g_assert_not_reached(); 4520 } 4521 return; 4522 illegal_op: 4523 gen_illegal_opcode(s); 4524 return; 4525 unknown_op: 4526 gen_unknown_opcode(env, s); 4527 } 4528 4529 #include "decode-new.h" 4530 #include "emit.c.inc" 4531 #include "decode-new.c.inc" 4532 4533 void tcg_x86_init(void) 4534 { 4535 static const char reg_names[CPU_NB_REGS][4] = { 4536 #ifdef TARGET_X86_64 4537 [R_EAX] = "rax", 4538 [R_EBX] = "rbx", 4539 [R_ECX] = "rcx", 4540 [R_EDX] = "rdx", 4541 [R_ESI] = "rsi", 4542 [R_EDI] = "rdi", 4543 [R_EBP] = "rbp", 4544 [R_ESP] = "rsp", 4545 [8] = "r8", 4546 [9] = "r9", 4547 [10] = "r10", 4548 [11] = "r11", 4549 [12] = "r12", 4550 [13] = "r13", 4551 [14] = "r14", 4552 [15] = "r15", 4553 #else 4554 [R_EAX] = "eax", 4555 [R_EBX] = "ebx", 4556 [R_ECX] = "ecx", 4557 [R_EDX] = "edx", 4558 [R_ESI] = "esi", 4559 [R_EDI] = "edi", 4560 [R_EBP] = "ebp", 4561 [R_ESP] = "esp", 4562 #endif 4563 }; 4564 static const char eip_name[] = { 4565 #ifdef TARGET_X86_64 4566 "rip" 4567 #else 4568 "eip" 4569 #endif 4570 }; 4571 static const char seg_base_names[6][8] = { 4572 [R_CS] = "cs_base", 4573 [R_DS] = "ds_base", 4574 [R_ES] = "es_base", 4575 [R_FS] = "fs_base", 4576 [R_GS] = "gs_base", 4577 [R_SS] = "ss_base", 4578 }; 4579 static const char bnd_regl_names[4][8] = { 4580 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb" 4581 }; 4582 static const char bnd_regu_names[4][8] = { 4583 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" 4584 }; 4585 int i; 4586 4587 cpu_cc_op = tcg_global_mem_new_i32(tcg_env, 4588 offsetof(CPUX86State, cc_op), "cc_op"); 4589 cpu_cc_dst = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_dst), 4590 "cc_dst"); 4591 cpu_cc_src = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src), 4592 "cc_src"); 4593 cpu_cc_src2 = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src2), 4594 "cc_src2"); 4595 cpu_eip = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, eip), eip_name); 4596 4597 for (i = 0; i < CPU_NB_REGS; ++i) { 4598 cpu_regs[i] = tcg_global_mem_new(tcg_env, 4599 offsetof(CPUX86State, regs[i]), 4600 reg_names[i]); 4601 } 4602 4603 for (i = 0; i < 6; ++i) { 4604 cpu_seg_base[i] 4605 = tcg_global_mem_new(tcg_env, 4606 offsetof(CPUX86State, segs[i].base), 4607 seg_base_names[i]); 4608 } 4609 4610 for (i = 0; i < 4; ++i) { 4611 cpu_bndl[i] 4612 = tcg_global_mem_new_i64(tcg_env, 4613 offsetof(CPUX86State, bnd_regs[i].lb), 4614 bnd_regl_names[i]); 4615 cpu_bndu[i] 4616 = tcg_global_mem_new_i64(tcg_env, 4617 offsetof(CPUX86State, bnd_regs[i].ub), 4618 bnd_regu_names[i]); 4619 } 4620 } 4621 4622 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 4623 { 4624 DisasContext *dc = container_of(dcbase, DisasContext, base); 4625 CPUX86State *env = cpu_env(cpu); 4626 uint32_t flags = dc->base.tb->flags; 4627 uint32_t cflags = tb_cflags(dc->base.tb); 4628 int cpl = (flags >> HF_CPL_SHIFT) & 3; 4629 int iopl = (flags >> IOPL_SHIFT) & 3; 4630 4631 dc->cs_base = dc->base.tb->cs_base; 4632 dc->pc_save = dc->base.pc_next; 4633 dc->flags = flags; 4634 #ifndef CONFIG_USER_ONLY 4635 dc->cpl = cpl; 4636 dc->iopl = iopl; 4637 #endif 4638 4639 /* We make some simplifying assumptions; validate they're correct. */ 4640 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); 4641 g_assert(CPL(dc) == cpl); 4642 g_assert(IOPL(dc) == iopl); 4643 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0)); 4644 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0)); 4645 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0)); 4646 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0)); 4647 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0)); 4648 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0)); 4649 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0)); 4650 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0)); 4651 4652 dc->cc_op = CC_OP_DYNAMIC; 4653 dc->cc_op_dirty = false; 4654 /* select memory access functions */ 4655 dc->mem_index = cpu_mmu_index(cpu, false); 4656 dc->cpuid_features = env->features[FEAT_1_EDX]; 4657 dc->cpuid_ext_features = env->features[FEAT_1_ECX]; 4658 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; 4659 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; 4660 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; 4661 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX]; 4662 dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX]; 4663 dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; 4664 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || 4665 (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 4666 /* 4667 * If jmp_opt, we want to handle each string instruction individually. 4668 * For icount also disable repz optimization so that each iteration 4669 * is accounted separately. 4670 */ 4671 dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT); 4672 4673 dc->T0 = tcg_temp_new(); 4674 dc->T1 = tcg_temp_new(); 4675 dc->A0 = tcg_temp_new(); 4676 4677 dc->tmp0 = tcg_temp_new(); 4678 dc->tmp1_i64 = tcg_temp_new_i64(); 4679 dc->tmp2_i32 = tcg_temp_new_i32(); 4680 dc->tmp3_i32 = tcg_temp_new_i32(); 4681 dc->tmp4 = tcg_temp_new(); 4682 dc->cc_srcT = tcg_temp_new(); 4683 } 4684 4685 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) 4686 { 4687 } 4688 4689 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 4690 { 4691 DisasContext *dc = container_of(dcbase, DisasContext, base); 4692 target_ulong pc_arg = dc->base.pc_next; 4693 4694 dc->prev_insn_start = dc->base.insn_start; 4695 dc->prev_insn_end = tcg_last_op(); 4696 if (tb_cflags(dcbase->tb) & CF_PCREL) { 4697 pc_arg &= ~TARGET_PAGE_MASK; 4698 } 4699 tcg_gen_insn_start(pc_arg, dc->cc_op); 4700 } 4701 4702 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 4703 { 4704 DisasContext *dc = container_of(dcbase, DisasContext, base); 4705 bool orig_cc_op_dirty = dc->cc_op_dirty; 4706 CCOp orig_cc_op = dc->cc_op; 4707 target_ulong orig_pc_save = dc->pc_save; 4708 4709 #ifdef TARGET_VSYSCALL_PAGE 4710 /* 4711 * Detect entry into the vsyscall page and invoke the syscall. 4712 */ 4713 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) { 4714 gen_exception(dc, EXCP_VSYSCALL); 4715 dc->base.pc_next = dc->pc + 1; 4716 return; 4717 } 4718 #endif 4719 4720 switch (sigsetjmp(dc->jmpbuf, 0)) { 4721 case 0: 4722 disas_insn(dc, cpu); 4723 break; 4724 case 1: 4725 gen_exception_gpf(dc); 4726 break; 4727 case 2: 4728 /* Restore state that may affect the next instruction. */ 4729 dc->pc = dc->base.pc_next; 4730 /* 4731 * TODO: These save/restore can be removed after the table-based 4732 * decoder is complete; we will be decoding the insn completely 4733 * before any code generation that might affect these variables. 4734 */ 4735 dc->cc_op_dirty = orig_cc_op_dirty; 4736 dc->cc_op = orig_cc_op; 4737 dc->pc_save = orig_pc_save; 4738 /* END TODO */ 4739 dc->base.num_insns--; 4740 tcg_remove_ops_after(dc->prev_insn_end); 4741 dc->base.insn_start = dc->prev_insn_start; 4742 dc->base.is_jmp = DISAS_TOO_MANY; 4743 return; 4744 default: 4745 g_assert_not_reached(); 4746 } 4747 4748 /* 4749 * Instruction decoding completed (possibly with #GP if the 4750 * 15-byte boundary was exceeded). 4751 */ 4752 dc->base.pc_next = dc->pc; 4753 if (dc->base.is_jmp == DISAS_NEXT) { 4754 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) { 4755 /* 4756 * If single step mode, we generate only one instruction and 4757 * generate an exception. 4758 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 4759 * the flag and abort the translation to give the irqs a 4760 * chance to happen. 4761 */ 4762 dc->base.is_jmp = DISAS_EOB_NEXT; 4763 } else if (!is_same_page(&dc->base, dc->base.pc_next)) { 4764 dc->base.is_jmp = DISAS_TOO_MANY; 4765 } 4766 } 4767 } 4768 4769 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 4770 { 4771 DisasContext *dc = container_of(dcbase, DisasContext, base); 4772 4773 switch (dc->base.is_jmp) { 4774 case DISAS_NORETURN: 4775 break; 4776 case DISAS_TOO_MANY: 4777 gen_update_cc_op(dc); 4778 gen_jmp_rel_csize(dc, 0, 0); 4779 break; 4780 case DISAS_EOB_NEXT: 4781 gen_update_cc_op(dc); 4782 gen_update_eip_cur(dc); 4783 /* fall through */ 4784 case DISAS_EOB_ONLY: 4785 gen_eob(dc); 4786 break; 4787 case DISAS_EOB_INHIBIT_IRQ: 4788 gen_update_cc_op(dc); 4789 gen_update_eip_cur(dc); 4790 gen_eob_inhibit_irq(dc); 4791 break; 4792 case DISAS_JUMP: 4793 gen_jr(dc); 4794 break; 4795 default: 4796 g_assert_not_reached(); 4797 } 4798 } 4799 4800 static const TranslatorOps i386_tr_ops = { 4801 .init_disas_context = i386_tr_init_disas_context, 4802 .tb_start = i386_tr_tb_start, 4803 .insn_start = i386_tr_insn_start, 4804 .translate_insn = i386_tr_translate_insn, 4805 .tb_stop = i386_tr_tb_stop, 4806 }; 4807 4808 /* generate intermediate code for basic block 'tb'. */ 4809 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns, 4810 vaddr pc, void *host_pc) 4811 { 4812 DisasContext dc; 4813 4814 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); 4815 } 4816