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