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 30 #include "exec/helper-proto.h" 31 #include "exec/helper-gen.h" 32 #include "helper-tcg.h" 33 34 #include "exec/log.h" 35 36 #define PREFIX_REPZ 0x01 37 #define PREFIX_REPNZ 0x02 38 #define PREFIX_LOCK 0x04 39 #define PREFIX_DATA 0x08 40 #define PREFIX_ADR 0x10 41 #define PREFIX_VEX 0x20 42 #define PREFIX_REX 0x40 43 44 #ifdef TARGET_X86_64 45 # define ctztl ctz64 46 # define clztl clz64 47 #else 48 # define ctztl ctz32 49 # define clztl clz32 50 #endif 51 52 /* For a switch indexed by MODRM, match all memory operands for a given OP. */ 53 #define CASE_MODRM_MEM_OP(OP) \ 54 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 55 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 56 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7 57 58 #define CASE_MODRM_OP(OP) \ 59 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 60 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 61 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \ 62 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7 63 64 //#define MACRO_TEST 1 65 66 /* global register indexes */ 67 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2; 68 static TCGv cpu_eip; 69 static TCGv_i32 cpu_cc_op; 70 static TCGv cpu_regs[CPU_NB_REGS]; 71 static TCGv cpu_seg_base[6]; 72 static TCGv_i64 cpu_bndl[4]; 73 static TCGv_i64 cpu_bndu[4]; 74 75 #include "exec/gen-icount.h" 76 77 typedef struct DisasContext { 78 DisasContextBase base; 79 80 target_ulong pc; /* pc = eip + cs_base */ 81 target_ulong cs_base; /* base of CS segment */ 82 target_ulong pc_save; 83 84 MemOp aflag; 85 MemOp dflag; 86 87 int8_t override; /* -1 if no override, else R_CS, R_DS, etc */ 88 uint8_t prefix; 89 90 bool has_modrm; 91 uint8_t modrm; 92 93 #ifndef CONFIG_USER_ONLY 94 uint8_t cpl; /* code priv level */ 95 uint8_t iopl; /* i/o priv level */ 96 #endif 97 uint8_t vex_l; /* vex vector length */ 98 uint8_t vex_v; /* vex vvvv register, without 1's complement. */ 99 uint8_t popl_esp_hack; /* for correct popl with esp base handling */ 100 uint8_t rip_offset; /* only used in x86_64, but left for simplicity */ 101 102 #ifdef TARGET_X86_64 103 uint8_t rex_r; 104 uint8_t rex_x; 105 uint8_t rex_b; 106 #endif 107 bool vex_w; /* used by AVX even on 32-bit processors */ 108 bool jmp_opt; /* use direct block chaining for direct jumps */ 109 bool repz_opt; /* optimize jumps within repz instructions */ 110 bool cc_op_dirty; 111 112 CCOp cc_op; /* current CC operation */ 113 int mem_index; /* select memory access functions */ 114 uint32_t flags; /* all execution flags */ 115 int cpuid_features; 116 int cpuid_ext_features; 117 int cpuid_ext2_features; 118 int cpuid_ext3_features; 119 int cpuid_7_0_ebx_features; 120 int cpuid_7_0_ecx_features; 121 int cpuid_xsave_features; 122 123 /* TCG local temps */ 124 TCGv cc_srcT; 125 TCGv A0; 126 TCGv T0; 127 TCGv T1; 128 129 /* TCG local register indexes (only used inside old micro ops) */ 130 TCGv tmp0; 131 TCGv tmp4; 132 TCGv_i32 tmp2_i32; 133 TCGv_i32 tmp3_i32; 134 TCGv_i64 tmp1_i64; 135 136 sigjmp_buf jmpbuf; 137 TCGOp *prev_insn_end; 138 } DisasContext; 139 140 #define DISAS_EOB_ONLY DISAS_TARGET_0 141 #define DISAS_EOB_NEXT DISAS_TARGET_1 142 #define DISAS_EOB_INHIBIT_IRQ DISAS_TARGET_2 143 #define DISAS_JUMP DISAS_TARGET_3 144 145 /* The environment in which user-only runs is constrained. */ 146 #ifdef CONFIG_USER_ONLY 147 #define PE(S) true 148 #define CPL(S) 3 149 #define IOPL(S) 0 150 #define SVME(S) false 151 #define GUEST(S) false 152 #else 153 #define PE(S) (((S)->flags & HF_PE_MASK) != 0) 154 #define CPL(S) ((S)->cpl) 155 #define IOPL(S) ((S)->iopl) 156 #define SVME(S) (((S)->flags & HF_SVME_MASK) != 0) 157 #define GUEST(S) (((S)->flags & HF_GUEST_MASK) != 0) 158 #endif 159 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64) 160 #define VM86(S) false 161 #define CODE32(S) true 162 #define SS32(S) true 163 #define ADDSEG(S) false 164 #else 165 #define VM86(S) (((S)->flags & HF_VM_MASK) != 0) 166 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0) 167 #define SS32(S) (((S)->flags & HF_SS32_MASK) != 0) 168 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0) 169 #endif 170 #if !defined(TARGET_X86_64) 171 #define CODE64(S) false 172 #define LMA(S) false 173 #elif defined(CONFIG_USER_ONLY) 174 #define CODE64(S) true 175 #define LMA(S) true 176 #else 177 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0) 178 #define LMA(S) (((S)->flags & HF_LMA_MASK) != 0) 179 #endif 180 181 #ifdef TARGET_X86_64 182 #define REX_PREFIX(S) (((S)->prefix & PREFIX_REX) != 0) 183 #define REX_W(S) ((S)->vex_w) 184 #define REX_R(S) ((S)->rex_r + 0) 185 #define REX_X(S) ((S)->rex_x + 0) 186 #define REX_B(S) ((S)->rex_b + 0) 187 #else 188 #define REX_PREFIX(S) false 189 #define REX_W(S) false 190 #define REX_R(S) 0 191 #define REX_X(S) 0 192 #define REX_B(S) 0 193 #endif 194 195 /* 196 * Many sysemu-only helpers are not reachable for user-only. 197 * Define stub generators here, so that we need not either sprinkle 198 * ifdefs through the translator, nor provide the helper function. 199 */ 200 #define STUB_HELPER(NAME, ...) \ 201 static inline void gen_helper_##NAME(__VA_ARGS__) \ 202 { qemu_build_not_reached(); } 203 204 #ifdef CONFIG_USER_ONLY 205 STUB_HELPER(clgi, TCGv_env env) 206 STUB_HELPER(flush_page, TCGv_env env, TCGv addr) 207 STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs) 208 STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port) 209 STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port) 210 STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port) 211 STUB_HELPER(monitor, TCGv_env env, TCGv addr) 212 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs) 213 STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 214 STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 215 STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 216 STUB_HELPER(rdmsr, TCGv_env env) 217 STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg) 218 STUB_HELPER(get_dr, TCGv ret, TCGv_env env, TCGv_i32 reg) 219 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val) 220 STUB_HELPER(stgi, TCGv_env env) 221 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type) 222 STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag) 223 STUB_HELPER(vmmcall, TCGv_env env) 224 STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs) 225 STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag) 226 STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val) 227 STUB_HELPER(wrmsr, TCGv_env env) 228 #endif 229 230 static void gen_eob(DisasContext *s); 231 static void gen_jr(DisasContext *s); 232 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num); 233 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num); 234 static void gen_op(DisasContext *s1, int op, MemOp ot, int d); 235 static void gen_exception_gpf(DisasContext *s); 236 237 /* i386 arith/logic operations */ 238 enum { 239 OP_ADDL, 240 OP_ORL, 241 OP_ADCL, 242 OP_SBBL, 243 OP_ANDL, 244 OP_SUBL, 245 OP_XORL, 246 OP_CMPL, 247 }; 248 249 /* i386 shift ops */ 250 enum { 251 OP_ROL, 252 OP_ROR, 253 OP_RCL, 254 OP_RCR, 255 OP_SHL, 256 OP_SHR, 257 OP_SHL1, /* undocumented */ 258 OP_SAR = 7, 259 }; 260 261 enum { 262 JCC_O, 263 JCC_B, 264 JCC_Z, 265 JCC_BE, 266 JCC_S, 267 JCC_P, 268 JCC_L, 269 JCC_LE, 270 }; 271 272 enum { 273 /* I386 int registers */ 274 OR_EAX, /* MUST be even numbered */ 275 OR_ECX, 276 OR_EDX, 277 OR_EBX, 278 OR_ESP, 279 OR_EBP, 280 OR_ESI, 281 OR_EDI, 282 283 OR_TMP0 = 16, /* temporary operand register */ 284 OR_TMP1, 285 OR_A0, /* temporary register used when doing address evaluation */ 286 }; 287 288 enum { 289 USES_CC_DST = 1, 290 USES_CC_SRC = 2, 291 USES_CC_SRC2 = 4, 292 USES_CC_SRCT = 8, 293 }; 294 295 /* Bit set if the global variable is live after setting CC_OP to X. */ 296 static const uint8_t cc_op_live[CC_OP_NB] = { 297 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 298 [CC_OP_EFLAGS] = USES_CC_SRC, 299 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC, 300 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC, 301 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 302 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT, 303 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 304 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST, 305 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC, 306 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC, 307 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC, 308 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC, 309 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC, 310 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC, 311 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2, 312 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 313 [CC_OP_CLR] = 0, 314 [CC_OP_POPCNT] = USES_CC_SRC, 315 }; 316 317 static void set_cc_op(DisasContext *s, CCOp op) 318 { 319 int dead; 320 321 if (s->cc_op == op) { 322 return; 323 } 324 325 /* Discard CC computation that will no longer be used. */ 326 dead = cc_op_live[s->cc_op] & ~cc_op_live[op]; 327 if (dead & USES_CC_DST) { 328 tcg_gen_discard_tl(cpu_cc_dst); 329 } 330 if (dead & USES_CC_SRC) { 331 tcg_gen_discard_tl(cpu_cc_src); 332 } 333 if (dead & USES_CC_SRC2) { 334 tcg_gen_discard_tl(cpu_cc_src2); 335 } 336 if (dead & USES_CC_SRCT) { 337 tcg_gen_discard_tl(s->cc_srcT); 338 } 339 340 if (op == CC_OP_DYNAMIC) { 341 /* The DYNAMIC setting is translator only, and should never be 342 stored. Thus we always consider it clean. */ 343 s->cc_op_dirty = false; 344 } else { 345 /* Discard any computed CC_OP value (see shifts). */ 346 if (s->cc_op == CC_OP_DYNAMIC) { 347 tcg_gen_discard_i32(cpu_cc_op); 348 } 349 s->cc_op_dirty = true; 350 } 351 s->cc_op = op; 352 } 353 354 static void gen_update_cc_op(DisasContext *s) 355 { 356 if (s->cc_op_dirty) { 357 tcg_gen_movi_i32(cpu_cc_op, s->cc_op); 358 s->cc_op_dirty = false; 359 } 360 } 361 362 #ifdef TARGET_X86_64 363 364 #define NB_OP_SIZES 4 365 366 #else /* !TARGET_X86_64 */ 367 368 #define NB_OP_SIZES 3 369 370 #endif /* !TARGET_X86_64 */ 371 372 #if HOST_BIG_ENDIAN 373 #define REG_B_OFFSET (sizeof(target_ulong) - 1) 374 #define REG_H_OFFSET (sizeof(target_ulong) - 2) 375 #define REG_W_OFFSET (sizeof(target_ulong) - 2) 376 #define REG_L_OFFSET (sizeof(target_ulong) - 4) 377 #define REG_LH_OFFSET (sizeof(target_ulong) - 8) 378 #else 379 #define REG_B_OFFSET 0 380 #define REG_H_OFFSET 1 381 #define REG_W_OFFSET 0 382 #define REG_L_OFFSET 0 383 #define REG_LH_OFFSET 4 384 #endif 385 386 /* In instruction encodings for byte register accesses the 387 * register number usually indicates "low 8 bits of register N"; 388 * however there are some special cases where N 4..7 indicates 389 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return 390 * true for this special case, false otherwise. 391 */ 392 static inline bool byte_reg_is_xH(DisasContext *s, int reg) 393 { 394 /* Any time the REX prefix is present, byte registers are uniform */ 395 if (reg < 4 || REX_PREFIX(s)) { 396 return false; 397 } 398 return true; 399 } 400 401 /* Select the size of a push/pop operation. */ 402 static inline MemOp mo_pushpop(DisasContext *s, MemOp ot) 403 { 404 if (CODE64(s)) { 405 return ot == MO_16 ? MO_16 : MO_64; 406 } else { 407 return ot; 408 } 409 } 410 411 /* Select the size of the stack pointer. */ 412 static inline MemOp mo_stacksize(DisasContext *s) 413 { 414 return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16; 415 } 416 417 /* Select only size 64 else 32. Used for SSE operand sizes. */ 418 static inline MemOp mo_64_32(MemOp ot) 419 { 420 #ifdef TARGET_X86_64 421 return ot == MO_64 ? MO_64 : MO_32; 422 #else 423 return MO_32; 424 #endif 425 } 426 427 /* Select size 8 if lsb of B is clear, else OT. Used for decoding 428 byte vs word opcodes. */ 429 static inline MemOp mo_b_d(int b, MemOp ot) 430 { 431 return b & 1 ? ot : MO_8; 432 } 433 434 /* Select size 8 if lsb of B is clear, else OT capped at 32. 435 Used for decoding operand size of port opcodes. */ 436 static inline MemOp mo_b_d32(int b, MemOp ot) 437 { 438 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8; 439 } 440 441 static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0) 442 { 443 switch(ot) { 444 case MO_8: 445 if (!byte_reg_is_xH(s, reg)) { 446 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8); 447 } else { 448 tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8); 449 } 450 break; 451 case MO_16: 452 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16); 453 break; 454 case MO_32: 455 /* For x86_64, this sets the higher half of register to zero. 456 For i386, this is equivalent to a mov. */ 457 tcg_gen_ext32u_tl(cpu_regs[reg], t0); 458 break; 459 #ifdef TARGET_X86_64 460 case MO_64: 461 tcg_gen_mov_tl(cpu_regs[reg], t0); 462 break; 463 #endif 464 default: 465 tcg_abort(); 466 } 467 } 468 469 static inline 470 void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg) 471 { 472 if (ot == MO_8 && byte_reg_is_xH(s, reg)) { 473 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8); 474 } else { 475 tcg_gen_mov_tl(t0, cpu_regs[reg]); 476 } 477 } 478 479 static void gen_add_A0_im(DisasContext *s, int val) 480 { 481 tcg_gen_addi_tl(s->A0, s->A0, val); 482 if (!CODE64(s)) { 483 tcg_gen_ext32u_tl(s->A0, s->A0); 484 } 485 } 486 487 static inline void gen_op_jmp_v(DisasContext *s, TCGv dest) 488 { 489 tcg_gen_mov_tl(cpu_eip, dest); 490 s->pc_save = -1; 491 } 492 493 static inline 494 void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val) 495 { 496 tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val); 497 gen_op_mov_reg_v(s, size, reg, s->tmp0); 498 } 499 500 static inline void gen_op_add_reg_T0(DisasContext *s, MemOp size, int reg) 501 { 502 tcg_gen_add_tl(s->tmp0, cpu_regs[reg], s->T0); 503 gen_op_mov_reg_v(s, size, reg, s->tmp0); 504 } 505 506 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 507 { 508 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE); 509 } 510 511 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 512 { 513 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE); 514 } 515 516 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d) 517 { 518 if (d == OR_TMP0) { 519 gen_op_st_v(s, idx, s->T0, s->A0); 520 } else { 521 gen_op_mov_reg_v(s, idx, d, s->T0); 522 } 523 } 524 525 static void gen_update_eip_cur(DisasContext *s) 526 { 527 assert(s->pc_save != -1); 528 if (TARGET_TB_PCREL) { 529 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save); 530 } else { 531 tcg_gen_movi_tl(cpu_eip, s->base.pc_next - s->cs_base); 532 } 533 s->pc_save = s->base.pc_next; 534 } 535 536 static void gen_update_eip_next(DisasContext *s) 537 { 538 assert(s->pc_save != -1); 539 if (TARGET_TB_PCREL) { 540 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save); 541 } else { 542 tcg_gen_movi_tl(cpu_eip, s->pc - s->cs_base); 543 } 544 s->pc_save = s->pc; 545 } 546 547 static int cur_insn_len(DisasContext *s) 548 { 549 return s->pc - s->base.pc_next; 550 } 551 552 static TCGv_i32 cur_insn_len_i32(DisasContext *s) 553 { 554 return tcg_constant_i32(cur_insn_len(s)); 555 } 556 557 static TCGv_i32 eip_next_i32(DisasContext *s) 558 { 559 assert(s->pc_save != -1); 560 /* 561 * This function has two users: lcall_real (always 16-bit mode), and 562 * iret_protected (16, 32, or 64-bit mode). IRET only uses the value 563 * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is 564 * why passing a 32-bit value isn't broken. To avoid using this where 565 * we shouldn't, return -1 in 64-bit mode so that execution goes into 566 * the weeds quickly. 567 */ 568 if (CODE64(s)) { 569 return tcg_constant_i32(-1); 570 } 571 if (TARGET_TB_PCREL) { 572 TCGv_i32 ret = tcg_temp_new_i32(); 573 tcg_gen_trunc_tl_i32(ret, cpu_eip); 574 tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save); 575 return ret; 576 } else { 577 return tcg_constant_i32(s->pc - s->cs_base); 578 } 579 } 580 581 static TCGv eip_next_tl(DisasContext *s) 582 { 583 assert(s->pc_save != -1); 584 if (TARGET_TB_PCREL) { 585 TCGv ret = tcg_temp_new(); 586 tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save); 587 return ret; 588 } else { 589 return tcg_constant_tl(s->pc - s->cs_base); 590 } 591 } 592 593 static TCGv eip_cur_tl(DisasContext *s) 594 { 595 assert(s->pc_save != -1); 596 if (TARGET_TB_PCREL) { 597 TCGv ret = tcg_temp_new(); 598 tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save); 599 return ret; 600 } else { 601 return tcg_constant_tl(s->base.pc_next - s->cs_base); 602 } 603 } 604 605 /* Compute SEG:REG into A0. SEG is selected from the override segment 606 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to 607 indicate no override. */ 608 static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0, 609 int def_seg, int ovr_seg) 610 { 611 switch (aflag) { 612 #ifdef TARGET_X86_64 613 case MO_64: 614 if (ovr_seg < 0) { 615 tcg_gen_mov_tl(s->A0, a0); 616 return; 617 } 618 break; 619 #endif 620 case MO_32: 621 /* 32 bit address */ 622 if (ovr_seg < 0 && ADDSEG(s)) { 623 ovr_seg = def_seg; 624 } 625 if (ovr_seg < 0) { 626 tcg_gen_ext32u_tl(s->A0, a0); 627 return; 628 } 629 break; 630 case MO_16: 631 /* 16 bit address */ 632 tcg_gen_ext16u_tl(s->A0, a0); 633 a0 = s->A0; 634 if (ovr_seg < 0) { 635 if (ADDSEG(s)) { 636 ovr_seg = def_seg; 637 } else { 638 return; 639 } 640 } 641 break; 642 default: 643 tcg_abort(); 644 } 645 646 if (ovr_seg >= 0) { 647 TCGv seg = cpu_seg_base[ovr_seg]; 648 649 if (aflag == MO_64) { 650 tcg_gen_add_tl(s->A0, a0, seg); 651 } else if (CODE64(s)) { 652 tcg_gen_ext32u_tl(s->A0, a0); 653 tcg_gen_add_tl(s->A0, s->A0, seg); 654 } else { 655 tcg_gen_add_tl(s->A0, a0, seg); 656 tcg_gen_ext32u_tl(s->A0, s->A0); 657 } 658 } 659 } 660 661 static inline void gen_string_movl_A0_ESI(DisasContext *s) 662 { 663 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override); 664 } 665 666 static inline void gen_string_movl_A0_EDI(DisasContext *s) 667 { 668 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1); 669 } 670 671 static inline void gen_op_movl_T0_Dshift(DisasContext *s, MemOp ot) 672 { 673 tcg_gen_ld32s_tl(s->T0, cpu_env, offsetof(CPUX86State, df)); 674 tcg_gen_shli_tl(s->T0, s->T0, ot); 675 }; 676 677 static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign) 678 { 679 switch (size) { 680 case MO_8: 681 if (sign) { 682 tcg_gen_ext8s_tl(dst, src); 683 } else { 684 tcg_gen_ext8u_tl(dst, src); 685 } 686 return dst; 687 case MO_16: 688 if (sign) { 689 tcg_gen_ext16s_tl(dst, src); 690 } else { 691 tcg_gen_ext16u_tl(dst, src); 692 } 693 return dst; 694 #ifdef TARGET_X86_64 695 case MO_32: 696 if (sign) { 697 tcg_gen_ext32s_tl(dst, src); 698 } else { 699 tcg_gen_ext32u_tl(dst, src); 700 } 701 return dst; 702 #endif 703 default: 704 return src; 705 } 706 } 707 708 static void gen_extu(MemOp ot, TCGv reg) 709 { 710 gen_ext_tl(reg, reg, ot, false); 711 } 712 713 static void gen_exts(MemOp ot, TCGv reg) 714 { 715 gen_ext_tl(reg, reg, ot, true); 716 } 717 718 static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1) 719 { 720 tcg_gen_mov_tl(s->tmp0, cpu_regs[R_ECX]); 721 gen_extu(s->aflag, s->tmp0); 722 tcg_gen_brcondi_tl(cond, s->tmp0, 0, label1); 723 } 724 725 static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1) 726 { 727 gen_op_j_ecx(s, TCG_COND_EQ, label1); 728 } 729 730 static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1) 731 { 732 gen_op_j_ecx(s, TCG_COND_NE, label1); 733 } 734 735 static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n) 736 { 737 switch (ot) { 738 case MO_8: 739 gen_helper_inb(v, cpu_env, n); 740 break; 741 case MO_16: 742 gen_helper_inw(v, cpu_env, n); 743 break; 744 case MO_32: 745 gen_helper_inl(v, cpu_env, n); 746 break; 747 default: 748 tcg_abort(); 749 } 750 } 751 752 static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n) 753 { 754 switch (ot) { 755 case MO_8: 756 gen_helper_outb(cpu_env, v, n); 757 break; 758 case MO_16: 759 gen_helper_outw(cpu_env, v, n); 760 break; 761 case MO_32: 762 gen_helper_outl(cpu_env, v, n); 763 break; 764 default: 765 tcg_abort(); 766 } 767 } 768 769 /* 770 * Validate that access to [port, port + 1<<ot) is allowed. 771 * Raise #GP, or VMM exit if not. 772 */ 773 static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port, 774 uint32_t svm_flags) 775 { 776 #ifdef CONFIG_USER_ONLY 777 /* 778 * We do not implement the ioperm(2) syscall, so the TSS check 779 * will always fail. 780 */ 781 gen_exception_gpf(s); 782 return false; 783 #else 784 if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) { 785 gen_helper_check_io(cpu_env, port, tcg_constant_i32(1 << ot)); 786 } 787 if (GUEST(s)) { 788 gen_update_cc_op(s); 789 gen_update_eip_cur(s); 790 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) { 791 svm_flags |= SVM_IOIO_REP_MASK; 792 } 793 svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot); 794 gen_helper_svm_check_io(cpu_env, port, 795 tcg_constant_i32(svm_flags), 796 cur_insn_len_i32(s)); 797 } 798 return true; 799 #endif 800 } 801 802 static void gen_movs(DisasContext *s, MemOp ot) 803 { 804 gen_string_movl_A0_ESI(s); 805 gen_op_ld_v(s, ot, s->T0, s->A0); 806 gen_string_movl_A0_EDI(s); 807 gen_op_st_v(s, ot, s->T0, s->A0); 808 gen_op_movl_T0_Dshift(s, ot); 809 gen_op_add_reg_T0(s, s->aflag, R_ESI); 810 gen_op_add_reg_T0(s, s->aflag, R_EDI); 811 } 812 813 static void gen_op_update1_cc(DisasContext *s) 814 { 815 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 816 } 817 818 static void gen_op_update2_cc(DisasContext *s) 819 { 820 tcg_gen_mov_tl(cpu_cc_src, s->T1); 821 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 822 } 823 824 static void gen_op_update3_cc(DisasContext *s, TCGv reg) 825 { 826 tcg_gen_mov_tl(cpu_cc_src2, reg); 827 tcg_gen_mov_tl(cpu_cc_src, s->T1); 828 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 829 } 830 831 static inline void gen_op_testl_T0_T1_cc(DisasContext *s) 832 { 833 tcg_gen_and_tl(cpu_cc_dst, s->T0, s->T1); 834 } 835 836 static void gen_op_update_neg_cc(DisasContext *s) 837 { 838 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 839 tcg_gen_neg_tl(cpu_cc_src, s->T0); 840 tcg_gen_movi_tl(s->cc_srcT, 0); 841 } 842 843 /* compute all eflags to cc_src */ 844 static void gen_compute_eflags(DisasContext *s) 845 { 846 TCGv zero, dst, src1, src2; 847 int live, dead; 848 849 if (s->cc_op == CC_OP_EFLAGS) { 850 return; 851 } 852 if (s->cc_op == CC_OP_CLR) { 853 tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P); 854 set_cc_op(s, CC_OP_EFLAGS); 855 return; 856 } 857 858 zero = NULL; 859 dst = cpu_cc_dst; 860 src1 = cpu_cc_src; 861 src2 = cpu_cc_src2; 862 863 /* Take care to not read values that are not live. */ 864 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT; 865 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2); 866 if (dead) { 867 zero = tcg_const_tl(0); 868 if (dead & USES_CC_DST) { 869 dst = zero; 870 } 871 if (dead & USES_CC_SRC) { 872 src1 = zero; 873 } 874 if (dead & USES_CC_SRC2) { 875 src2 = zero; 876 } 877 } 878 879 gen_update_cc_op(s); 880 gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op); 881 set_cc_op(s, CC_OP_EFLAGS); 882 883 if (dead) { 884 tcg_temp_free(zero); 885 } 886 } 887 888 typedef struct CCPrepare { 889 TCGCond cond; 890 TCGv reg; 891 TCGv reg2; 892 target_ulong imm; 893 target_ulong mask; 894 bool use_reg2; 895 bool no_setcond; 896 } CCPrepare; 897 898 /* compute eflags.C to reg */ 899 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg) 900 { 901 TCGv t0, t1; 902 int size, shift; 903 904 switch (s->cc_op) { 905 case CC_OP_SUBB ... CC_OP_SUBQ: 906 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */ 907 size = s->cc_op - CC_OP_SUBB; 908 t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false); 909 /* If no temporary was used, be careful not to alias t1 and t0. */ 910 t0 = t1 == cpu_cc_src ? s->tmp0 : reg; 911 tcg_gen_mov_tl(t0, s->cc_srcT); 912 gen_extu(size, t0); 913 goto add_sub; 914 915 case CC_OP_ADDB ... CC_OP_ADDQ: 916 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */ 917 size = s->cc_op - CC_OP_ADDB; 918 t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false); 919 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false); 920 add_sub: 921 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0, 922 .reg2 = t1, .mask = -1, .use_reg2 = true }; 923 924 case CC_OP_LOGICB ... CC_OP_LOGICQ: 925 case CC_OP_CLR: 926 case CC_OP_POPCNT: 927 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 }; 928 929 case CC_OP_INCB ... CC_OP_INCQ: 930 case CC_OP_DECB ... CC_OP_DECQ: 931 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 932 .mask = -1, .no_setcond = true }; 933 934 case CC_OP_SHLB ... CC_OP_SHLQ: 935 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */ 936 size = s->cc_op - CC_OP_SHLB; 937 shift = (8 << size) - 1; 938 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 939 .mask = (target_ulong)1 << shift }; 940 941 case CC_OP_MULB ... CC_OP_MULQ: 942 return (CCPrepare) { .cond = TCG_COND_NE, 943 .reg = cpu_cc_src, .mask = -1 }; 944 945 case CC_OP_BMILGB ... CC_OP_BMILGQ: 946 size = s->cc_op - CC_OP_BMILGB; 947 t0 = gen_ext_tl(reg, cpu_cc_src, size, false); 948 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 }; 949 950 case CC_OP_ADCX: 951 case CC_OP_ADCOX: 952 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst, 953 .mask = -1, .no_setcond = true }; 954 955 case CC_OP_EFLAGS: 956 case CC_OP_SARB ... CC_OP_SARQ: 957 /* CC_SRC & 1 */ 958 return (CCPrepare) { .cond = TCG_COND_NE, 959 .reg = cpu_cc_src, .mask = CC_C }; 960 961 default: 962 /* The need to compute only C from CC_OP_DYNAMIC is important 963 in efficiently implementing e.g. INC at the start of a TB. */ 964 gen_update_cc_op(s); 965 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src, 966 cpu_cc_src2, cpu_cc_op); 967 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg, 968 .mask = -1, .no_setcond = true }; 969 } 970 } 971 972 /* compute eflags.P to reg */ 973 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg) 974 { 975 gen_compute_eflags(s); 976 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 977 .mask = CC_P }; 978 } 979 980 /* compute eflags.S to reg */ 981 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg) 982 { 983 switch (s->cc_op) { 984 case CC_OP_DYNAMIC: 985 gen_compute_eflags(s); 986 /* FALLTHRU */ 987 case CC_OP_EFLAGS: 988 case CC_OP_ADCX: 989 case CC_OP_ADOX: 990 case CC_OP_ADCOX: 991 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 992 .mask = CC_S }; 993 case CC_OP_CLR: 994 case CC_OP_POPCNT: 995 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 }; 996 default: 997 { 998 MemOp size = (s->cc_op - CC_OP_ADDB) & 3; 999 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true); 1000 return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 }; 1001 } 1002 } 1003 } 1004 1005 /* compute eflags.O to reg */ 1006 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg) 1007 { 1008 switch (s->cc_op) { 1009 case CC_OP_ADOX: 1010 case CC_OP_ADCOX: 1011 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2, 1012 .mask = -1, .no_setcond = true }; 1013 case CC_OP_CLR: 1014 case CC_OP_POPCNT: 1015 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 }; 1016 default: 1017 gen_compute_eflags(s); 1018 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 1019 .mask = CC_O }; 1020 } 1021 } 1022 1023 /* compute eflags.Z to reg */ 1024 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg) 1025 { 1026 switch (s->cc_op) { 1027 case CC_OP_DYNAMIC: 1028 gen_compute_eflags(s); 1029 /* FALLTHRU */ 1030 case CC_OP_EFLAGS: 1031 case CC_OP_ADCX: 1032 case CC_OP_ADOX: 1033 case CC_OP_ADCOX: 1034 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 1035 .mask = CC_Z }; 1036 case CC_OP_CLR: 1037 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 }; 1038 case CC_OP_POPCNT: 1039 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src, 1040 .mask = -1 }; 1041 default: 1042 { 1043 MemOp size = (s->cc_op - CC_OP_ADDB) & 3; 1044 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false); 1045 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 }; 1046 } 1047 } 1048 } 1049 1050 /* perform a conditional store into register 'reg' according to jump opcode 1051 value 'b'. In the fast case, T0 is guaranted not to be used. */ 1052 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg) 1053 { 1054 int inv, jcc_op, cond; 1055 MemOp size; 1056 CCPrepare cc; 1057 TCGv t0; 1058 1059 inv = b & 1; 1060 jcc_op = (b >> 1) & 7; 1061 1062 switch (s->cc_op) { 1063 case CC_OP_SUBB ... CC_OP_SUBQ: 1064 /* We optimize relational operators for the cmp/jcc case. */ 1065 size = s->cc_op - CC_OP_SUBB; 1066 switch (jcc_op) { 1067 case JCC_BE: 1068 tcg_gen_mov_tl(s->tmp4, s->cc_srcT); 1069 gen_extu(size, s->tmp4); 1070 t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false); 1071 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->tmp4, 1072 .reg2 = t0, .mask = -1, .use_reg2 = true }; 1073 break; 1074 1075 case JCC_L: 1076 cond = TCG_COND_LT; 1077 goto fast_jcc_l; 1078 case JCC_LE: 1079 cond = TCG_COND_LE; 1080 fast_jcc_l: 1081 tcg_gen_mov_tl(s->tmp4, s->cc_srcT); 1082 gen_exts(size, s->tmp4); 1083 t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, true); 1084 cc = (CCPrepare) { .cond = cond, .reg = s->tmp4, 1085 .reg2 = t0, .mask = -1, .use_reg2 = true }; 1086 break; 1087 1088 default: 1089 goto slow_jcc; 1090 } 1091 break; 1092 1093 default: 1094 slow_jcc: 1095 /* This actually generates good code for JC, JZ and JS. */ 1096 switch (jcc_op) { 1097 case JCC_O: 1098 cc = gen_prepare_eflags_o(s, reg); 1099 break; 1100 case JCC_B: 1101 cc = gen_prepare_eflags_c(s, reg); 1102 break; 1103 case JCC_Z: 1104 cc = gen_prepare_eflags_z(s, reg); 1105 break; 1106 case JCC_BE: 1107 gen_compute_eflags(s); 1108 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 1109 .mask = CC_Z | CC_C }; 1110 break; 1111 case JCC_S: 1112 cc = gen_prepare_eflags_s(s, reg); 1113 break; 1114 case JCC_P: 1115 cc = gen_prepare_eflags_p(s, reg); 1116 break; 1117 case JCC_L: 1118 gen_compute_eflags(s); 1119 if (reg == cpu_cc_src) { 1120 reg = s->tmp0; 1121 } 1122 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */ 1123 tcg_gen_xor_tl(reg, reg, cpu_cc_src); 1124 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg, 1125 .mask = CC_S }; 1126 break; 1127 default: 1128 case JCC_LE: 1129 gen_compute_eflags(s); 1130 if (reg == cpu_cc_src) { 1131 reg = s->tmp0; 1132 } 1133 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */ 1134 tcg_gen_xor_tl(reg, reg, cpu_cc_src); 1135 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg, 1136 .mask = CC_S | CC_Z }; 1137 break; 1138 } 1139 break; 1140 } 1141 1142 if (inv) { 1143 cc.cond = tcg_invert_cond(cc.cond); 1144 } 1145 return cc; 1146 } 1147 1148 static void gen_setcc1(DisasContext *s, int b, TCGv reg) 1149 { 1150 CCPrepare cc = gen_prepare_cc(s, b, reg); 1151 1152 if (cc.no_setcond) { 1153 if (cc.cond == TCG_COND_EQ) { 1154 tcg_gen_xori_tl(reg, cc.reg, 1); 1155 } else { 1156 tcg_gen_mov_tl(reg, cc.reg); 1157 } 1158 return; 1159 } 1160 1161 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 && 1162 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) { 1163 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask)); 1164 tcg_gen_andi_tl(reg, reg, 1); 1165 return; 1166 } 1167 if (cc.mask != -1) { 1168 tcg_gen_andi_tl(reg, cc.reg, cc.mask); 1169 cc.reg = reg; 1170 } 1171 if (cc.use_reg2) { 1172 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2); 1173 } else { 1174 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm); 1175 } 1176 } 1177 1178 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg) 1179 { 1180 gen_setcc1(s, JCC_B << 1, reg); 1181 } 1182 1183 /* generate a conditional jump to label 'l1' according to jump opcode 1184 value 'b'. In the fast case, T0 is guaranted not to be used. */ 1185 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1) 1186 { 1187 CCPrepare cc = gen_prepare_cc(s, b, s->T0); 1188 1189 if (cc.mask != -1) { 1190 tcg_gen_andi_tl(s->T0, cc.reg, cc.mask); 1191 cc.reg = s->T0; 1192 } 1193 if (cc.use_reg2) { 1194 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1195 } else { 1196 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1197 } 1198 } 1199 1200 /* Generate a conditional jump to label 'l1' according to jump opcode 1201 value 'b'. In the fast case, T0 is guaranted not to be used. 1202 A translation block must end soon. */ 1203 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1) 1204 { 1205 CCPrepare cc = gen_prepare_cc(s, b, s->T0); 1206 1207 gen_update_cc_op(s); 1208 if (cc.mask != -1) { 1209 tcg_gen_andi_tl(s->T0, cc.reg, cc.mask); 1210 cc.reg = s->T0; 1211 } 1212 set_cc_op(s, CC_OP_DYNAMIC); 1213 if (cc.use_reg2) { 1214 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1215 } else { 1216 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1217 } 1218 } 1219 1220 /* XXX: does not work with gdbstub "ice" single step - not a 1221 serious problem */ 1222 static TCGLabel *gen_jz_ecx_string(DisasContext *s) 1223 { 1224 TCGLabel *l1 = gen_new_label(); 1225 TCGLabel *l2 = gen_new_label(); 1226 gen_op_jnz_ecx(s, l1); 1227 gen_set_label(l2); 1228 gen_jmp_rel_csize(s, 0, 1); 1229 gen_set_label(l1); 1230 return l2; 1231 } 1232 1233 static void gen_stos(DisasContext *s, MemOp ot) 1234 { 1235 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX); 1236 gen_string_movl_A0_EDI(s); 1237 gen_op_st_v(s, ot, s->T0, s->A0); 1238 gen_op_movl_T0_Dshift(s, ot); 1239 gen_op_add_reg_T0(s, s->aflag, R_EDI); 1240 } 1241 1242 static void gen_lods(DisasContext *s, MemOp ot) 1243 { 1244 gen_string_movl_A0_ESI(s); 1245 gen_op_ld_v(s, ot, s->T0, s->A0); 1246 gen_op_mov_reg_v(s, ot, R_EAX, s->T0); 1247 gen_op_movl_T0_Dshift(s, ot); 1248 gen_op_add_reg_T0(s, s->aflag, R_ESI); 1249 } 1250 1251 static void gen_scas(DisasContext *s, MemOp ot) 1252 { 1253 gen_string_movl_A0_EDI(s); 1254 gen_op_ld_v(s, ot, s->T1, s->A0); 1255 gen_op(s, OP_CMPL, ot, R_EAX); 1256 gen_op_movl_T0_Dshift(s, ot); 1257 gen_op_add_reg_T0(s, s->aflag, R_EDI); 1258 } 1259 1260 static void gen_cmps(DisasContext *s, MemOp ot) 1261 { 1262 gen_string_movl_A0_EDI(s); 1263 gen_op_ld_v(s, ot, s->T1, s->A0); 1264 gen_string_movl_A0_ESI(s); 1265 gen_op(s, OP_CMPL, ot, OR_TMP0); 1266 gen_op_movl_T0_Dshift(s, ot); 1267 gen_op_add_reg_T0(s, s->aflag, R_ESI); 1268 gen_op_add_reg_T0(s, s->aflag, R_EDI); 1269 } 1270 1271 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot) 1272 { 1273 if (s->flags & HF_IOBPT_MASK) { 1274 #ifdef CONFIG_USER_ONLY 1275 /* user-mode cpu should not be in IOBPT mode */ 1276 g_assert_not_reached(); 1277 #else 1278 TCGv_i32 t_size = tcg_constant_i32(1 << ot); 1279 TCGv t_next = eip_next_tl(s); 1280 gen_helper_bpt_io(cpu_env, t_port, t_size, t_next); 1281 #endif /* CONFIG_USER_ONLY */ 1282 } 1283 } 1284 1285 static void gen_ins(DisasContext *s, MemOp ot) 1286 { 1287 gen_string_movl_A0_EDI(s); 1288 /* Note: we must do this dummy write first to be restartable in 1289 case of page fault. */ 1290 tcg_gen_movi_tl(s->T0, 0); 1291 gen_op_st_v(s, ot, s->T0, s->A0); 1292 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 1293 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); 1294 gen_helper_in_func(ot, s->T0, s->tmp2_i32); 1295 gen_op_st_v(s, ot, s->T0, s->A0); 1296 gen_op_movl_T0_Dshift(s, ot); 1297 gen_op_add_reg_T0(s, s->aflag, R_EDI); 1298 gen_bpt_io(s, s->tmp2_i32, ot); 1299 } 1300 1301 static void gen_outs(DisasContext *s, MemOp ot) 1302 { 1303 gen_string_movl_A0_ESI(s); 1304 gen_op_ld_v(s, ot, s->T0, s->A0); 1305 1306 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 1307 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); 1308 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0); 1309 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 1310 gen_op_movl_T0_Dshift(s, ot); 1311 gen_op_add_reg_T0(s, s->aflag, R_ESI); 1312 gen_bpt_io(s, s->tmp2_i32, ot); 1313 } 1314 1315 /* Generate jumps to current or next instruction */ 1316 static void gen_repz(DisasContext *s, MemOp ot, 1317 void (*fn)(DisasContext *s, MemOp ot)) 1318 { 1319 TCGLabel *l2; 1320 gen_update_cc_op(s); 1321 l2 = gen_jz_ecx_string(s); 1322 fn(s, ot); 1323 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 1324 /* 1325 * A loop would cause two single step exceptions if ECX = 1 1326 * before rep string_insn 1327 */ 1328 if (s->repz_opt) { 1329 gen_op_jz_ecx(s, l2); 1330 } 1331 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1332 } 1333 1334 #define GEN_REPZ(op) \ 1335 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot) \ 1336 { gen_repz(s, ot, gen_##op); } 1337 1338 static void gen_repz2(DisasContext *s, MemOp ot, int nz, 1339 void (*fn)(DisasContext *s, MemOp ot)) 1340 { 1341 TCGLabel *l2; 1342 gen_update_cc_op(s); 1343 l2 = gen_jz_ecx_string(s); 1344 fn(s, ot); 1345 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 1346 gen_update_cc_op(s); 1347 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); 1348 if (s->repz_opt) { 1349 gen_op_jz_ecx(s, l2); 1350 } 1351 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1352 } 1353 1354 #define GEN_REPZ2(op) \ 1355 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, int nz) \ 1356 { gen_repz2(s, ot, nz, gen_##op); } 1357 1358 GEN_REPZ(movs) 1359 GEN_REPZ(stos) 1360 GEN_REPZ(lods) 1361 GEN_REPZ(ins) 1362 GEN_REPZ(outs) 1363 GEN_REPZ2(scas) 1364 GEN_REPZ2(cmps) 1365 1366 static void gen_helper_fp_arith_ST0_FT0(int op) 1367 { 1368 switch (op) { 1369 case 0: 1370 gen_helper_fadd_ST0_FT0(cpu_env); 1371 break; 1372 case 1: 1373 gen_helper_fmul_ST0_FT0(cpu_env); 1374 break; 1375 case 2: 1376 gen_helper_fcom_ST0_FT0(cpu_env); 1377 break; 1378 case 3: 1379 gen_helper_fcom_ST0_FT0(cpu_env); 1380 break; 1381 case 4: 1382 gen_helper_fsub_ST0_FT0(cpu_env); 1383 break; 1384 case 5: 1385 gen_helper_fsubr_ST0_FT0(cpu_env); 1386 break; 1387 case 6: 1388 gen_helper_fdiv_ST0_FT0(cpu_env); 1389 break; 1390 case 7: 1391 gen_helper_fdivr_ST0_FT0(cpu_env); 1392 break; 1393 } 1394 } 1395 1396 /* NOTE the exception in "r" op ordering */ 1397 static void gen_helper_fp_arith_STN_ST0(int op, int opreg) 1398 { 1399 TCGv_i32 tmp = tcg_const_i32(opreg); 1400 switch (op) { 1401 case 0: 1402 gen_helper_fadd_STN_ST0(cpu_env, tmp); 1403 break; 1404 case 1: 1405 gen_helper_fmul_STN_ST0(cpu_env, tmp); 1406 break; 1407 case 4: 1408 gen_helper_fsubr_STN_ST0(cpu_env, tmp); 1409 break; 1410 case 5: 1411 gen_helper_fsub_STN_ST0(cpu_env, tmp); 1412 break; 1413 case 6: 1414 gen_helper_fdivr_STN_ST0(cpu_env, tmp); 1415 break; 1416 case 7: 1417 gen_helper_fdiv_STN_ST0(cpu_env, tmp); 1418 break; 1419 } 1420 } 1421 1422 static void gen_exception(DisasContext *s, int trapno) 1423 { 1424 gen_update_cc_op(s); 1425 gen_update_eip_cur(s); 1426 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno)); 1427 s->base.is_jmp = DISAS_NORETURN; 1428 } 1429 1430 /* Generate #UD for the current instruction. The assumption here is that 1431 the instruction is known, but it isn't allowed in the current cpu mode. */ 1432 static void gen_illegal_opcode(DisasContext *s) 1433 { 1434 gen_exception(s, EXCP06_ILLOP); 1435 } 1436 1437 /* Generate #GP for the current instruction. */ 1438 static void gen_exception_gpf(DisasContext *s) 1439 { 1440 gen_exception(s, EXCP0D_GPF); 1441 } 1442 1443 /* Check for cpl == 0; if not, raise #GP and return false. */ 1444 static bool check_cpl0(DisasContext *s) 1445 { 1446 if (CPL(s) == 0) { 1447 return true; 1448 } 1449 gen_exception_gpf(s); 1450 return false; 1451 } 1452 1453 /* If vm86, check for iopl == 3; if not, raise #GP and return false. */ 1454 static bool check_vm86_iopl(DisasContext *s) 1455 { 1456 if (!VM86(s) || IOPL(s) == 3) { 1457 return true; 1458 } 1459 gen_exception_gpf(s); 1460 return false; 1461 } 1462 1463 /* Check for iopl allowing access; if not, raise #GP and return false. */ 1464 static bool check_iopl(DisasContext *s) 1465 { 1466 if (VM86(s) ? IOPL(s) == 3 : CPL(s) <= IOPL(s)) { 1467 return true; 1468 } 1469 gen_exception_gpf(s); 1470 return false; 1471 } 1472 1473 /* if d == OR_TMP0, it means memory operand (address in A0) */ 1474 static void gen_op(DisasContext *s1, int op, MemOp ot, int d) 1475 { 1476 if (d != OR_TMP0) { 1477 if (s1->prefix & PREFIX_LOCK) { 1478 /* Lock prefix when destination is not memory. */ 1479 gen_illegal_opcode(s1); 1480 return; 1481 } 1482 gen_op_mov_v_reg(s1, ot, s1->T0, d); 1483 } else if (!(s1->prefix & PREFIX_LOCK)) { 1484 gen_op_ld_v(s1, ot, s1->T0, s1->A0); 1485 } 1486 switch(op) { 1487 case OP_ADCL: 1488 gen_compute_eflags_c(s1, s1->tmp4); 1489 if (s1->prefix & PREFIX_LOCK) { 1490 tcg_gen_add_tl(s1->T0, s1->tmp4, s1->T1); 1491 tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0, 1492 s1->mem_index, ot | MO_LE); 1493 } else { 1494 tcg_gen_add_tl(s1->T0, s1->T0, s1->T1); 1495 tcg_gen_add_tl(s1->T0, s1->T0, s1->tmp4); 1496 gen_op_st_rm_T0_A0(s1, ot, d); 1497 } 1498 gen_op_update3_cc(s1, s1->tmp4); 1499 set_cc_op(s1, CC_OP_ADCB + ot); 1500 break; 1501 case OP_SBBL: 1502 gen_compute_eflags_c(s1, s1->tmp4); 1503 if (s1->prefix & PREFIX_LOCK) { 1504 tcg_gen_add_tl(s1->T0, s1->T1, s1->tmp4); 1505 tcg_gen_neg_tl(s1->T0, s1->T0); 1506 tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0, 1507 s1->mem_index, ot | MO_LE); 1508 } else { 1509 tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1); 1510 tcg_gen_sub_tl(s1->T0, s1->T0, s1->tmp4); 1511 gen_op_st_rm_T0_A0(s1, ot, d); 1512 } 1513 gen_op_update3_cc(s1, s1->tmp4); 1514 set_cc_op(s1, CC_OP_SBBB + ot); 1515 break; 1516 case OP_ADDL: 1517 if (s1->prefix & PREFIX_LOCK) { 1518 tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T1, 1519 s1->mem_index, ot | MO_LE); 1520 } else { 1521 tcg_gen_add_tl(s1->T0, s1->T0, s1->T1); 1522 gen_op_st_rm_T0_A0(s1, ot, d); 1523 } 1524 gen_op_update2_cc(s1); 1525 set_cc_op(s1, CC_OP_ADDB + ot); 1526 break; 1527 case OP_SUBL: 1528 if (s1->prefix & PREFIX_LOCK) { 1529 tcg_gen_neg_tl(s1->T0, s1->T1); 1530 tcg_gen_atomic_fetch_add_tl(s1->cc_srcT, s1->A0, s1->T0, 1531 s1->mem_index, ot | MO_LE); 1532 tcg_gen_sub_tl(s1->T0, s1->cc_srcT, s1->T1); 1533 } else { 1534 tcg_gen_mov_tl(s1->cc_srcT, s1->T0); 1535 tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1); 1536 gen_op_st_rm_T0_A0(s1, ot, d); 1537 } 1538 gen_op_update2_cc(s1); 1539 set_cc_op(s1, CC_OP_SUBB + ot); 1540 break; 1541 default: 1542 case OP_ANDL: 1543 if (s1->prefix & PREFIX_LOCK) { 1544 tcg_gen_atomic_and_fetch_tl(s1->T0, s1->A0, s1->T1, 1545 s1->mem_index, ot | MO_LE); 1546 } else { 1547 tcg_gen_and_tl(s1->T0, s1->T0, s1->T1); 1548 gen_op_st_rm_T0_A0(s1, ot, d); 1549 } 1550 gen_op_update1_cc(s1); 1551 set_cc_op(s1, CC_OP_LOGICB + ot); 1552 break; 1553 case OP_ORL: 1554 if (s1->prefix & PREFIX_LOCK) { 1555 tcg_gen_atomic_or_fetch_tl(s1->T0, s1->A0, s1->T1, 1556 s1->mem_index, ot | MO_LE); 1557 } else { 1558 tcg_gen_or_tl(s1->T0, s1->T0, s1->T1); 1559 gen_op_st_rm_T0_A0(s1, ot, d); 1560 } 1561 gen_op_update1_cc(s1); 1562 set_cc_op(s1, CC_OP_LOGICB + ot); 1563 break; 1564 case OP_XORL: 1565 if (s1->prefix & PREFIX_LOCK) { 1566 tcg_gen_atomic_xor_fetch_tl(s1->T0, s1->A0, s1->T1, 1567 s1->mem_index, ot | MO_LE); 1568 } else { 1569 tcg_gen_xor_tl(s1->T0, s1->T0, s1->T1); 1570 gen_op_st_rm_T0_A0(s1, ot, d); 1571 } 1572 gen_op_update1_cc(s1); 1573 set_cc_op(s1, CC_OP_LOGICB + ot); 1574 break; 1575 case OP_CMPL: 1576 tcg_gen_mov_tl(cpu_cc_src, s1->T1); 1577 tcg_gen_mov_tl(s1->cc_srcT, s1->T0); 1578 tcg_gen_sub_tl(cpu_cc_dst, s1->T0, s1->T1); 1579 set_cc_op(s1, CC_OP_SUBB + ot); 1580 break; 1581 } 1582 } 1583 1584 /* if d == OR_TMP0, it means memory operand (address in A0) */ 1585 static void gen_inc(DisasContext *s1, MemOp ot, int d, int c) 1586 { 1587 if (s1->prefix & PREFIX_LOCK) { 1588 if (d != OR_TMP0) { 1589 /* Lock prefix when destination is not memory */ 1590 gen_illegal_opcode(s1); 1591 return; 1592 } 1593 tcg_gen_movi_tl(s1->T0, c > 0 ? 1 : -1); 1594 tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0, 1595 s1->mem_index, ot | MO_LE); 1596 } else { 1597 if (d != OR_TMP0) { 1598 gen_op_mov_v_reg(s1, ot, s1->T0, d); 1599 } else { 1600 gen_op_ld_v(s1, ot, s1->T0, s1->A0); 1601 } 1602 tcg_gen_addi_tl(s1->T0, s1->T0, (c > 0 ? 1 : -1)); 1603 gen_op_st_rm_T0_A0(s1, ot, d); 1604 } 1605 1606 gen_compute_eflags_c(s1, cpu_cc_src); 1607 tcg_gen_mov_tl(cpu_cc_dst, s1->T0); 1608 set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot); 1609 } 1610 1611 static void gen_shift_flags(DisasContext *s, MemOp ot, TCGv result, 1612 TCGv shm1, TCGv count, bool is_right) 1613 { 1614 TCGv_i32 z32, s32, oldop; 1615 TCGv z_tl; 1616 1617 /* Store the results into the CC variables. If we know that the 1618 variable must be dead, store unconditionally. Otherwise we'll 1619 need to not disrupt the current contents. */ 1620 z_tl = tcg_const_tl(0); 1621 if (cc_op_live[s->cc_op] & USES_CC_DST) { 1622 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl, 1623 result, cpu_cc_dst); 1624 } else { 1625 tcg_gen_mov_tl(cpu_cc_dst, result); 1626 } 1627 if (cc_op_live[s->cc_op] & USES_CC_SRC) { 1628 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl, 1629 shm1, cpu_cc_src); 1630 } else { 1631 tcg_gen_mov_tl(cpu_cc_src, shm1); 1632 } 1633 tcg_temp_free(z_tl); 1634 1635 /* Get the two potential CC_OP values into temporaries. */ 1636 tcg_gen_movi_i32(s->tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot); 1637 if (s->cc_op == CC_OP_DYNAMIC) { 1638 oldop = cpu_cc_op; 1639 } else { 1640 tcg_gen_movi_i32(s->tmp3_i32, s->cc_op); 1641 oldop = s->tmp3_i32; 1642 } 1643 1644 /* Conditionally store the CC_OP value. */ 1645 z32 = tcg_const_i32(0); 1646 s32 = tcg_temp_new_i32(); 1647 tcg_gen_trunc_tl_i32(s32, count); 1648 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, s->tmp2_i32, oldop); 1649 tcg_temp_free_i32(z32); 1650 tcg_temp_free_i32(s32); 1651 1652 /* The CC_OP value is no longer predictable. */ 1653 set_cc_op(s, CC_OP_DYNAMIC); 1654 } 1655 1656 static void gen_shift_rm_T1(DisasContext *s, MemOp ot, int op1, 1657 int is_right, int is_arith) 1658 { 1659 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f); 1660 1661 /* load */ 1662 if (op1 == OR_TMP0) { 1663 gen_op_ld_v(s, ot, s->T0, s->A0); 1664 } else { 1665 gen_op_mov_v_reg(s, ot, s->T0, op1); 1666 } 1667 1668 tcg_gen_andi_tl(s->T1, s->T1, mask); 1669 tcg_gen_subi_tl(s->tmp0, s->T1, 1); 1670 1671 if (is_right) { 1672 if (is_arith) { 1673 gen_exts(ot, s->T0); 1674 tcg_gen_sar_tl(s->tmp0, s->T0, s->tmp0); 1675 tcg_gen_sar_tl(s->T0, s->T0, s->T1); 1676 } else { 1677 gen_extu(ot, s->T0); 1678 tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0); 1679 tcg_gen_shr_tl(s->T0, s->T0, s->T1); 1680 } 1681 } else { 1682 tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0); 1683 tcg_gen_shl_tl(s->T0, s->T0, s->T1); 1684 } 1685 1686 /* store */ 1687 gen_op_st_rm_T0_A0(s, ot, op1); 1688 1689 gen_shift_flags(s, ot, s->T0, s->tmp0, s->T1, is_right); 1690 } 1691 1692 static void gen_shift_rm_im(DisasContext *s, MemOp ot, int op1, int op2, 1693 int is_right, int is_arith) 1694 { 1695 int mask = (ot == MO_64 ? 0x3f : 0x1f); 1696 1697 /* load */ 1698 if (op1 == OR_TMP0) 1699 gen_op_ld_v(s, ot, s->T0, s->A0); 1700 else 1701 gen_op_mov_v_reg(s, ot, s->T0, op1); 1702 1703 op2 &= mask; 1704 if (op2 != 0) { 1705 if (is_right) { 1706 if (is_arith) { 1707 gen_exts(ot, s->T0); 1708 tcg_gen_sari_tl(s->tmp4, s->T0, op2 - 1); 1709 tcg_gen_sari_tl(s->T0, s->T0, op2); 1710 } else { 1711 gen_extu(ot, s->T0); 1712 tcg_gen_shri_tl(s->tmp4, s->T0, op2 - 1); 1713 tcg_gen_shri_tl(s->T0, s->T0, op2); 1714 } 1715 } else { 1716 tcg_gen_shli_tl(s->tmp4, s->T0, op2 - 1); 1717 tcg_gen_shli_tl(s->T0, s->T0, op2); 1718 } 1719 } 1720 1721 /* store */ 1722 gen_op_st_rm_T0_A0(s, ot, op1); 1723 1724 /* update eflags if non zero shift */ 1725 if (op2 != 0) { 1726 tcg_gen_mov_tl(cpu_cc_src, s->tmp4); 1727 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 1728 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot); 1729 } 1730 } 1731 1732 static void gen_rot_rm_T1(DisasContext *s, MemOp ot, int op1, int is_right) 1733 { 1734 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f); 1735 TCGv_i32 t0, t1; 1736 1737 /* load */ 1738 if (op1 == OR_TMP0) { 1739 gen_op_ld_v(s, ot, s->T0, s->A0); 1740 } else { 1741 gen_op_mov_v_reg(s, ot, s->T0, op1); 1742 } 1743 1744 tcg_gen_andi_tl(s->T1, s->T1, mask); 1745 1746 switch (ot) { 1747 case MO_8: 1748 /* Replicate the 8-bit input so that a 32-bit rotate works. */ 1749 tcg_gen_ext8u_tl(s->T0, s->T0); 1750 tcg_gen_muli_tl(s->T0, s->T0, 0x01010101); 1751 goto do_long; 1752 case MO_16: 1753 /* Replicate the 16-bit input so that a 32-bit rotate works. */ 1754 tcg_gen_deposit_tl(s->T0, s->T0, s->T0, 16, 16); 1755 goto do_long; 1756 do_long: 1757 #ifdef TARGET_X86_64 1758 case MO_32: 1759 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 1760 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 1761 if (is_right) { 1762 tcg_gen_rotr_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32); 1763 } else { 1764 tcg_gen_rotl_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32); 1765 } 1766 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 1767 break; 1768 #endif 1769 default: 1770 if (is_right) { 1771 tcg_gen_rotr_tl(s->T0, s->T0, s->T1); 1772 } else { 1773 tcg_gen_rotl_tl(s->T0, s->T0, s->T1); 1774 } 1775 break; 1776 } 1777 1778 /* store */ 1779 gen_op_st_rm_T0_A0(s, ot, op1); 1780 1781 /* We'll need the flags computed into CC_SRC. */ 1782 gen_compute_eflags(s); 1783 1784 /* The value that was "rotated out" is now present at the other end 1785 of the word. Compute C into CC_DST and O into CC_SRC2. Note that 1786 since we've computed the flags into CC_SRC, these variables are 1787 currently dead. */ 1788 if (is_right) { 1789 tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1); 1790 tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask); 1791 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1); 1792 } else { 1793 tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask); 1794 tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1); 1795 } 1796 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1); 1797 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst); 1798 1799 /* Now conditionally store the new CC_OP value. If the shift count 1800 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live. 1801 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out 1802 exactly as we computed above. */ 1803 t0 = tcg_const_i32(0); 1804 t1 = tcg_temp_new_i32(); 1805 tcg_gen_trunc_tl_i32(t1, s->T1); 1806 tcg_gen_movi_i32(s->tmp2_i32, CC_OP_ADCOX); 1807 tcg_gen_movi_i32(s->tmp3_i32, CC_OP_EFLAGS); 1808 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0, 1809 s->tmp2_i32, s->tmp3_i32); 1810 tcg_temp_free_i32(t0); 1811 tcg_temp_free_i32(t1); 1812 1813 /* The CC_OP value is no longer predictable. */ 1814 set_cc_op(s, CC_OP_DYNAMIC); 1815 } 1816 1817 static void gen_rot_rm_im(DisasContext *s, MemOp ot, int op1, int op2, 1818 int is_right) 1819 { 1820 int mask = (ot == MO_64 ? 0x3f : 0x1f); 1821 int shift; 1822 1823 /* load */ 1824 if (op1 == OR_TMP0) { 1825 gen_op_ld_v(s, ot, s->T0, s->A0); 1826 } else { 1827 gen_op_mov_v_reg(s, ot, s->T0, op1); 1828 } 1829 1830 op2 &= mask; 1831 if (op2 != 0) { 1832 switch (ot) { 1833 #ifdef TARGET_X86_64 1834 case MO_32: 1835 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 1836 if (is_right) { 1837 tcg_gen_rotri_i32(s->tmp2_i32, s->tmp2_i32, op2); 1838 } else { 1839 tcg_gen_rotli_i32(s->tmp2_i32, s->tmp2_i32, op2); 1840 } 1841 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 1842 break; 1843 #endif 1844 default: 1845 if (is_right) { 1846 tcg_gen_rotri_tl(s->T0, s->T0, op2); 1847 } else { 1848 tcg_gen_rotli_tl(s->T0, s->T0, op2); 1849 } 1850 break; 1851 case MO_8: 1852 mask = 7; 1853 goto do_shifts; 1854 case MO_16: 1855 mask = 15; 1856 do_shifts: 1857 shift = op2 & mask; 1858 if (is_right) { 1859 shift = mask + 1 - shift; 1860 } 1861 gen_extu(ot, s->T0); 1862 tcg_gen_shli_tl(s->tmp0, s->T0, shift); 1863 tcg_gen_shri_tl(s->T0, s->T0, mask + 1 - shift); 1864 tcg_gen_or_tl(s->T0, s->T0, s->tmp0); 1865 break; 1866 } 1867 } 1868 1869 /* store */ 1870 gen_op_st_rm_T0_A0(s, ot, op1); 1871 1872 if (op2 != 0) { 1873 /* Compute the flags into CC_SRC. */ 1874 gen_compute_eflags(s); 1875 1876 /* The value that was "rotated out" is now present at the other end 1877 of the word. Compute C into CC_DST and O into CC_SRC2. Note that 1878 since we've computed the flags into CC_SRC, these variables are 1879 currently dead. */ 1880 if (is_right) { 1881 tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1); 1882 tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask); 1883 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1); 1884 } else { 1885 tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask); 1886 tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1); 1887 } 1888 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1); 1889 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst); 1890 set_cc_op(s, CC_OP_ADCOX); 1891 } 1892 } 1893 1894 /* XXX: add faster immediate = 1 case */ 1895 static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1, 1896 int is_right) 1897 { 1898 gen_compute_eflags(s); 1899 assert(s->cc_op == CC_OP_EFLAGS); 1900 1901 /* load */ 1902 if (op1 == OR_TMP0) 1903 gen_op_ld_v(s, ot, s->T0, s->A0); 1904 else 1905 gen_op_mov_v_reg(s, ot, s->T0, op1); 1906 1907 if (is_right) { 1908 switch (ot) { 1909 case MO_8: 1910 gen_helper_rcrb(s->T0, cpu_env, s->T0, s->T1); 1911 break; 1912 case MO_16: 1913 gen_helper_rcrw(s->T0, cpu_env, s->T0, s->T1); 1914 break; 1915 case MO_32: 1916 gen_helper_rcrl(s->T0, cpu_env, s->T0, s->T1); 1917 break; 1918 #ifdef TARGET_X86_64 1919 case MO_64: 1920 gen_helper_rcrq(s->T0, cpu_env, s->T0, s->T1); 1921 break; 1922 #endif 1923 default: 1924 tcg_abort(); 1925 } 1926 } else { 1927 switch (ot) { 1928 case MO_8: 1929 gen_helper_rclb(s->T0, cpu_env, s->T0, s->T1); 1930 break; 1931 case MO_16: 1932 gen_helper_rclw(s->T0, cpu_env, s->T0, s->T1); 1933 break; 1934 case MO_32: 1935 gen_helper_rcll(s->T0, cpu_env, s->T0, s->T1); 1936 break; 1937 #ifdef TARGET_X86_64 1938 case MO_64: 1939 gen_helper_rclq(s->T0, cpu_env, s->T0, s->T1); 1940 break; 1941 #endif 1942 default: 1943 tcg_abort(); 1944 } 1945 } 1946 /* store */ 1947 gen_op_st_rm_T0_A0(s, ot, op1); 1948 } 1949 1950 /* XXX: add faster immediate case */ 1951 static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1, 1952 bool is_right, TCGv count_in) 1953 { 1954 target_ulong mask = (ot == MO_64 ? 63 : 31); 1955 TCGv count; 1956 1957 /* load */ 1958 if (op1 == OR_TMP0) { 1959 gen_op_ld_v(s, ot, s->T0, s->A0); 1960 } else { 1961 gen_op_mov_v_reg(s, ot, s->T0, op1); 1962 } 1963 1964 count = tcg_temp_new(); 1965 tcg_gen_andi_tl(count, count_in, mask); 1966 1967 switch (ot) { 1968 case MO_16: 1969 /* Note: we implement the Intel behaviour for shift count > 16. 1970 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A 1971 portion by constructing it as a 32-bit value. */ 1972 if (is_right) { 1973 tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16); 1974 tcg_gen_mov_tl(s->T1, s->T0); 1975 tcg_gen_mov_tl(s->T0, s->tmp0); 1976 } else { 1977 tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16); 1978 } 1979 /* 1980 * If TARGET_X86_64 defined then fall through into MO_32 case, 1981 * otherwise fall through default case. 1982 */ 1983 case MO_32: 1984 #ifdef TARGET_X86_64 1985 /* Concatenate the two 32-bit values and use a 64-bit shift. */ 1986 tcg_gen_subi_tl(s->tmp0, count, 1); 1987 if (is_right) { 1988 tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1); 1989 tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0); 1990 tcg_gen_shr_i64(s->T0, s->T0, count); 1991 } else { 1992 tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0); 1993 tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0); 1994 tcg_gen_shl_i64(s->T0, s->T0, count); 1995 tcg_gen_shri_i64(s->tmp0, s->tmp0, 32); 1996 tcg_gen_shri_i64(s->T0, s->T0, 32); 1997 } 1998 break; 1999 #endif 2000 default: 2001 tcg_gen_subi_tl(s->tmp0, count, 1); 2002 if (is_right) { 2003 tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0); 2004 2005 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 2006 tcg_gen_shr_tl(s->T0, s->T0, count); 2007 tcg_gen_shl_tl(s->T1, s->T1, s->tmp4); 2008 } else { 2009 tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0); 2010 if (ot == MO_16) { 2011 /* Only needed if count > 16, for Intel behaviour. */ 2012 tcg_gen_subfi_tl(s->tmp4, 33, count); 2013 tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4); 2014 tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4); 2015 } 2016 2017 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 2018 tcg_gen_shl_tl(s->T0, s->T0, count); 2019 tcg_gen_shr_tl(s->T1, s->T1, s->tmp4); 2020 } 2021 tcg_gen_movi_tl(s->tmp4, 0); 2022 tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4, 2023 s->tmp4, s->T1); 2024 tcg_gen_or_tl(s->T0, s->T0, s->T1); 2025 break; 2026 } 2027 2028 /* store */ 2029 gen_op_st_rm_T0_A0(s, ot, op1); 2030 2031 gen_shift_flags(s, ot, s->T0, s->tmp0, count, is_right); 2032 tcg_temp_free(count); 2033 } 2034 2035 static void gen_shift(DisasContext *s1, int op, MemOp ot, int d, int s) 2036 { 2037 if (s != OR_TMP1) 2038 gen_op_mov_v_reg(s1, ot, s1->T1, s); 2039 switch(op) { 2040 case OP_ROL: 2041 gen_rot_rm_T1(s1, ot, d, 0); 2042 break; 2043 case OP_ROR: 2044 gen_rot_rm_T1(s1, ot, d, 1); 2045 break; 2046 case OP_SHL: 2047 case OP_SHL1: 2048 gen_shift_rm_T1(s1, ot, d, 0, 0); 2049 break; 2050 case OP_SHR: 2051 gen_shift_rm_T1(s1, ot, d, 1, 0); 2052 break; 2053 case OP_SAR: 2054 gen_shift_rm_T1(s1, ot, d, 1, 1); 2055 break; 2056 case OP_RCL: 2057 gen_rotc_rm_T1(s1, ot, d, 0); 2058 break; 2059 case OP_RCR: 2060 gen_rotc_rm_T1(s1, ot, d, 1); 2061 break; 2062 } 2063 } 2064 2065 static void gen_shifti(DisasContext *s1, int op, MemOp ot, int d, int c) 2066 { 2067 switch(op) { 2068 case OP_ROL: 2069 gen_rot_rm_im(s1, ot, d, c, 0); 2070 break; 2071 case OP_ROR: 2072 gen_rot_rm_im(s1, ot, d, c, 1); 2073 break; 2074 case OP_SHL: 2075 case OP_SHL1: 2076 gen_shift_rm_im(s1, ot, d, c, 0, 0); 2077 break; 2078 case OP_SHR: 2079 gen_shift_rm_im(s1, ot, d, c, 1, 0); 2080 break; 2081 case OP_SAR: 2082 gen_shift_rm_im(s1, ot, d, c, 1, 1); 2083 break; 2084 default: 2085 /* currently not optimized */ 2086 tcg_gen_movi_tl(s1->T1, c); 2087 gen_shift(s1, op, ot, d, OR_TMP1); 2088 break; 2089 } 2090 } 2091 2092 #define X86_MAX_INSN_LENGTH 15 2093 2094 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes) 2095 { 2096 uint64_t pc = s->pc; 2097 2098 /* This is a subsequent insn that crosses a page boundary. */ 2099 if (s->base.num_insns > 1 && 2100 !is_same_page(&s->base, s->pc + num_bytes - 1)) { 2101 siglongjmp(s->jmpbuf, 2); 2102 } 2103 2104 s->pc += num_bytes; 2105 if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) { 2106 /* If the instruction's 16th byte is on a different page than the 1st, a 2107 * page fault on the second page wins over the general protection fault 2108 * caused by the instruction being too long. 2109 * This can happen even if the operand is only one byte long! 2110 */ 2111 if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) { 2112 volatile uint8_t unused = 2113 cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK); 2114 (void) unused; 2115 } 2116 siglongjmp(s->jmpbuf, 1); 2117 } 2118 2119 return pc; 2120 } 2121 2122 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s) 2123 { 2124 return translator_ldub(env, &s->base, advance_pc(env, s, 1)); 2125 } 2126 2127 static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s) 2128 { 2129 return translator_lduw(env, &s->base, advance_pc(env, s, 2)); 2130 } 2131 2132 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s) 2133 { 2134 return translator_lduw(env, &s->base, advance_pc(env, s, 2)); 2135 } 2136 2137 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s) 2138 { 2139 return translator_ldl(env, &s->base, advance_pc(env, s, 4)); 2140 } 2141 2142 #ifdef TARGET_X86_64 2143 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s) 2144 { 2145 return translator_ldq(env, &s->base, advance_pc(env, s, 8)); 2146 } 2147 #endif 2148 2149 /* Decompose an address. */ 2150 2151 typedef struct AddressParts { 2152 int def_seg; 2153 int base; 2154 int index; 2155 int scale; 2156 target_long disp; 2157 } AddressParts; 2158 2159 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s, 2160 int modrm) 2161 { 2162 int def_seg, base, index, scale, mod, rm; 2163 target_long disp; 2164 bool havesib; 2165 2166 def_seg = R_DS; 2167 index = -1; 2168 scale = 0; 2169 disp = 0; 2170 2171 mod = (modrm >> 6) & 3; 2172 rm = modrm & 7; 2173 base = rm | REX_B(s); 2174 2175 if (mod == 3) { 2176 /* Normally filtered out earlier, but including this path 2177 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */ 2178 goto done; 2179 } 2180 2181 switch (s->aflag) { 2182 case MO_64: 2183 case MO_32: 2184 havesib = 0; 2185 if (rm == 4) { 2186 int code = x86_ldub_code(env, s); 2187 scale = (code >> 6) & 3; 2188 index = ((code >> 3) & 7) | REX_X(s); 2189 if (index == 4) { 2190 index = -1; /* no index */ 2191 } 2192 base = (code & 7) | REX_B(s); 2193 havesib = 1; 2194 } 2195 2196 switch (mod) { 2197 case 0: 2198 if ((base & 7) == 5) { 2199 base = -1; 2200 disp = (int32_t)x86_ldl_code(env, s); 2201 if (CODE64(s) && !havesib) { 2202 base = -2; 2203 disp += s->pc + s->rip_offset; 2204 } 2205 } 2206 break; 2207 case 1: 2208 disp = (int8_t)x86_ldub_code(env, s); 2209 break; 2210 default: 2211 case 2: 2212 disp = (int32_t)x86_ldl_code(env, s); 2213 break; 2214 } 2215 2216 /* For correct popl handling with esp. */ 2217 if (base == R_ESP && s->popl_esp_hack) { 2218 disp += s->popl_esp_hack; 2219 } 2220 if (base == R_EBP || base == R_ESP) { 2221 def_seg = R_SS; 2222 } 2223 break; 2224 2225 case MO_16: 2226 if (mod == 0) { 2227 if (rm == 6) { 2228 base = -1; 2229 disp = x86_lduw_code(env, s); 2230 break; 2231 } 2232 } else if (mod == 1) { 2233 disp = (int8_t)x86_ldub_code(env, s); 2234 } else { 2235 disp = (int16_t)x86_lduw_code(env, s); 2236 } 2237 2238 switch (rm) { 2239 case 0: 2240 base = R_EBX; 2241 index = R_ESI; 2242 break; 2243 case 1: 2244 base = R_EBX; 2245 index = R_EDI; 2246 break; 2247 case 2: 2248 base = R_EBP; 2249 index = R_ESI; 2250 def_seg = R_SS; 2251 break; 2252 case 3: 2253 base = R_EBP; 2254 index = R_EDI; 2255 def_seg = R_SS; 2256 break; 2257 case 4: 2258 base = R_ESI; 2259 break; 2260 case 5: 2261 base = R_EDI; 2262 break; 2263 case 6: 2264 base = R_EBP; 2265 def_seg = R_SS; 2266 break; 2267 default: 2268 case 7: 2269 base = R_EBX; 2270 break; 2271 } 2272 break; 2273 2274 default: 2275 tcg_abort(); 2276 } 2277 2278 done: 2279 return (AddressParts){ def_seg, base, index, scale, disp }; 2280 } 2281 2282 /* Compute the address, with a minimum number of TCG ops. */ 2283 static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib) 2284 { 2285 TCGv ea = NULL; 2286 2287 if (a.index >= 0 && !is_vsib) { 2288 if (a.scale == 0) { 2289 ea = cpu_regs[a.index]; 2290 } else { 2291 tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale); 2292 ea = s->A0; 2293 } 2294 if (a.base >= 0) { 2295 tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]); 2296 ea = s->A0; 2297 } 2298 } else if (a.base >= 0) { 2299 ea = cpu_regs[a.base]; 2300 } 2301 if (!ea) { 2302 if (TARGET_TB_PCREL && a.base == -2) { 2303 /* With cpu_eip ~= pc_save, the expression is pc-relative. */ 2304 tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save); 2305 } else { 2306 tcg_gen_movi_tl(s->A0, a.disp); 2307 } 2308 ea = s->A0; 2309 } else if (a.disp != 0) { 2310 tcg_gen_addi_tl(s->A0, ea, a.disp); 2311 ea = s->A0; 2312 } 2313 2314 return ea; 2315 } 2316 2317 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) 2318 { 2319 AddressParts a = gen_lea_modrm_0(env, s, modrm); 2320 TCGv ea = gen_lea_modrm_1(s, a, false); 2321 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override); 2322 } 2323 2324 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm) 2325 { 2326 (void)gen_lea_modrm_0(env, s, modrm); 2327 } 2328 2329 /* Used for BNDCL, BNDCU, BNDCN. */ 2330 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm, 2331 TCGCond cond, TCGv_i64 bndv) 2332 { 2333 AddressParts a = gen_lea_modrm_0(env, s, modrm); 2334 TCGv ea = gen_lea_modrm_1(s, a, false); 2335 2336 tcg_gen_extu_tl_i64(s->tmp1_i64, ea); 2337 if (!CODE64(s)) { 2338 tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64); 2339 } 2340 tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv); 2341 tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64); 2342 gen_helper_bndck(cpu_env, s->tmp2_i32); 2343 } 2344 2345 /* used for LEA and MOV AX, mem */ 2346 static void gen_add_A0_ds_seg(DisasContext *s) 2347 { 2348 gen_lea_v_seg(s, s->aflag, s->A0, R_DS, s->override); 2349 } 2350 2351 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg == 2352 OR_TMP0 */ 2353 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm, 2354 MemOp ot, int reg, int is_store) 2355 { 2356 int mod, rm; 2357 2358 mod = (modrm >> 6) & 3; 2359 rm = (modrm & 7) | REX_B(s); 2360 if (mod == 3) { 2361 if (is_store) { 2362 if (reg != OR_TMP0) 2363 gen_op_mov_v_reg(s, ot, s->T0, reg); 2364 gen_op_mov_reg_v(s, ot, rm, s->T0); 2365 } else { 2366 gen_op_mov_v_reg(s, ot, s->T0, rm); 2367 if (reg != OR_TMP0) 2368 gen_op_mov_reg_v(s, ot, reg, s->T0); 2369 } 2370 } else { 2371 gen_lea_modrm(env, s, modrm); 2372 if (is_store) { 2373 if (reg != OR_TMP0) 2374 gen_op_mov_v_reg(s, ot, s->T0, reg); 2375 gen_op_st_v(s, ot, s->T0, s->A0); 2376 } else { 2377 gen_op_ld_v(s, ot, s->T0, s->A0); 2378 if (reg != OR_TMP0) 2379 gen_op_mov_reg_v(s, ot, reg, s->T0); 2380 } 2381 } 2382 } 2383 2384 static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot) 2385 { 2386 target_ulong ret; 2387 2388 switch (ot) { 2389 case MO_8: 2390 ret = x86_ldub_code(env, s); 2391 break; 2392 case MO_16: 2393 ret = x86_lduw_code(env, s); 2394 break; 2395 case MO_32: 2396 ret = x86_ldl_code(env, s); 2397 break; 2398 #ifdef TARGET_X86_64 2399 case MO_64: 2400 ret = x86_ldq_code(env, s); 2401 break; 2402 #endif 2403 default: 2404 g_assert_not_reached(); 2405 } 2406 return ret; 2407 } 2408 2409 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot) 2410 { 2411 uint32_t ret; 2412 2413 switch (ot) { 2414 case MO_8: 2415 ret = x86_ldub_code(env, s); 2416 break; 2417 case MO_16: 2418 ret = x86_lduw_code(env, s); 2419 break; 2420 case MO_32: 2421 #ifdef TARGET_X86_64 2422 case MO_64: 2423 #endif 2424 ret = x86_ldl_code(env, s); 2425 break; 2426 default: 2427 tcg_abort(); 2428 } 2429 return ret; 2430 } 2431 2432 static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot) 2433 { 2434 target_long ret; 2435 2436 switch (ot) { 2437 case MO_8: 2438 ret = (int8_t) x86_ldub_code(env, s); 2439 break; 2440 case MO_16: 2441 ret = (int16_t) x86_lduw_code(env, s); 2442 break; 2443 case MO_32: 2444 ret = (int32_t) x86_ldl_code(env, s); 2445 break; 2446 #ifdef TARGET_X86_64 2447 case MO_64: 2448 ret = x86_ldq_code(env, s); 2449 break; 2450 #endif 2451 default: 2452 g_assert_not_reached(); 2453 } 2454 return ret; 2455 } 2456 2457 static inline int insn_const_size(MemOp ot) 2458 { 2459 if (ot <= MO_32) { 2460 return 1 << ot; 2461 } else { 2462 return 4; 2463 } 2464 } 2465 2466 static void gen_jcc(DisasContext *s, int b, int diff) 2467 { 2468 TCGLabel *l1 = gen_new_label(); 2469 2470 gen_jcc1(s, b, l1); 2471 gen_jmp_rel_csize(s, 0, 1); 2472 gen_set_label(l1); 2473 gen_jmp_rel(s, s->dflag, diff, 0); 2474 } 2475 2476 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, MemOp ot, int b, 2477 int modrm, int reg) 2478 { 2479 CCPrepare cc; 2480 2481 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 2482 2483 cc = gen_prepare_cc(s, b, s->T1); 2484 if (cc.mask != -1) { 2485 TCGv t0 = tcg_temp_new(); 2486 tcg_gen_andi_tl(t0, cc.reg, cc.mask); 2487 cc.reg = t0; 2488 } 2489 if (!cc.use_reg2) { 2490 cc.reg2 = tcg_const_tl(cc.imm); 2491 } 2492 2493 tcg_gen_movcond_tl(cc.cond, s->T0, cc.reg, cc.reg2, 2494 s->T0, cpu_regs[reg]); 2495 gen_op_mov_reg_v(s, ot, reg, s->T0); 2496 2497 if (cc.mask != -1) { 2498 tcg_temp_free(cc.reg); 2499 } 2500 if (!cc.use_reg2) { 2501 tcg_temp_free(cc.reg2); 2502 } 2503 } 2504 2505 static inline void gen_op_movl_T0_seg(DisasContext *s, X86Seg seg_reg) 2506 { 2507 tcg_gen_ld32u_tl(s->T0, cpu_env, 2508 offsetof(CPUX86State,segs[seg_reg].selector)); 2509 } 2510 2511 static inline void gen_op_movl_seg_T0_vm(DisasContext *s, X86Seg seg_reg) 2512 { 2513 tcg_gen_ext16u_tl(s->T0, s->T0); 2514 tcg_gen_st32_tl(s->T0, cpu_env, 2515 offsetof(CPUX86State,segs[seg_reg].selector)); 2516 tcg_gen_shli_tl(cpu_seg_base[seg_reg], s->T0, 4); 2517 } 2518 2519 /* move T0 to seg_reg and compute if the CPU state may change. Never 2520 call this function with seg_reg == R_CS */ 2521 static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg) 2522 { 2523 if (PE(s) && !VM86(s)) { 2524 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 2525 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), s->tmp2_i32); 2526 /* abort translation because the addseg value may change or 2527 because ss32 may change. For R_SS, translation must always 2528 stop as a special handling must be done to disable hardware 2529 interrupts for the next instruction */ 2530 if (seg_reg == R_SS) { 2531 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 2532 } else if (CODE32(s) && seg_reg < R_FS) { 2533 s->base.is_jmp = DISAS_EOB_NEXT; 2534 } 2535 } else { 2536 gen_op_movl_seg_T0_vm(s, seg_reg); 2537 if (seg_reg == R_SS) { 2538 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 2539 } 2540 } 2541 } 2542 2543 static void gen_svm_check_intercept(DisasContext *s, uint32_t type) 2544 { 2545 /* no SVM activated; fast case */ 2546 if (likely(!GUEST(s))) { 2547 return; 2548 } 2549 gen_helper_svm_check_intercept(cpu_env, tcg_constant_i32(type)); 2550 } 2551 2552 static inline void gen_stack_update(DisasContext *s, int addend) 2553 { 2554 gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend); 2555 } 2556 2557 /* Generate a push. It depends on ss32, addseg and dflag. */ 2558 static void gen_push_v(DisasContext *s, TCGv val) 2559 { 2560 MemOp d_ot = mo_pushpop(s, s->dflag); 2561 MemOp a_ot = mo_stacksize(s); 2562 int size = 1 << d_ot; 2563 TCGv new_esp = s->A0; 2564 2565 tcg_gen_subi_tl(s->A0, cpu_regs[R_ESP], size); 2566 2567 if (!CODE64(s)) { 2568 if (ADDSEG(s)) { 2569 new_esp = s->tmp4; 2570 tcg_gen_mov_tl(new_esp, s->A0); 2571 } 2572 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2573 } 2574 2575 gen_op_st_v(s, d_ot, val, s->A0); 2576 gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp); 2577 } 2578 2579 /* two step pop is necessary for precise exceptions */ 2580 static MemOp gen_pop_T0(DisasContext *s) 2581 { 2582 MemOp d_ot = mo_pushpop(s, s->dflag); 2583 2584 gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1); 2585 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2586 2587 return d_ot; 2588 } 2589 2590 static inline void gen_pop_update(DisasContext *s, MemOp ot) 2591 { 2592 gen_stack_update(s, 1 << ot); 2593 } 2594 2595 static inline void gen_stack_A0(DisasContext *s) 2596 { 2597 gen_lea_v_seg(s, SS32(s) ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1); 2598 } 2599 2600 static void gen_pusha(DisasContext *s) 2601 { 2602 MemOp s_ot = SS32(s) ? MO_32 : MO_16; 2603 MemOp d_ot = s->dflag; 2604 int size = 1 << d_ot; 2605 int i; 2606 2607 for (i = 0; i < 8; i++) { 2608 tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], (i - 8) * size); 2609 gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1); 2610 gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0); 2611 } 2612 2613 gen_stack_update(s, -8 * size); 2614 } 2615 2616 static void gen_popa(DisasContext *s) 2617 { 2618 MemOp s_ot = SS32(s) ? MO_32 : MO_16; 2619 MemOp d_ot = s->dflag; 2620 int size = 1 << d_ot; 2621 int i; 2622 2623 for (i = 0; i < 8; i++) { 2624 /* ESP is not reloaded */ 2625 if (7 - i == R_ESP) { 2626 continue; 2627 } 2628 tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], i * size); 2629 gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1); 2630 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2631 gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0); 2632 } 2633 2634 gen_stack_update(s, 8 * size); 2635 } 2636 2637 static void gen_enter(DisasContext *s, int esp_addend, int level) 2638 { 2639 MemOp d_ot = mo_pushpop(s, s->dflag); 2640 MemOp a_ot = CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16; 2641 int size = 1 << d_ot; 2642 2643 /* Push BP; compute FrameTemp into T1. */ 2644 tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size); 2645 gen_lea_v_seg(s, a_ot, s->T1, R_SS, -1); 2646 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0); 2647 2648 level &= 31; 2649 if (level != 0) { 2650 int i; 2651 2652 /* Copy level-1 pointers from the previous frame. */ 2653 for (i = 1; i < level; ++i) { 2654 tcg_gen_subi_tl(s->A0, cpu_regs[R_EBP], size * i); 2655 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2656 gen_op_ld_v(s, d_ot, s->tmp0, s->A0); 2657 2658 tcg_gen_subi_tl(s->A0, s->T1, size * i); 2659 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2660 gen_op_st_v(s, d_ot, s->tmp0, s->A0); 2661 } 2662 2663 /* Push the current FrameTemp as the last level. */ 2664 tcg_gen_subi_tl(s->A0, s->T1, size * level); 2665 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1); 2666 gen_op_st_v(s, d_ot, s->T1, s->A0); 2667 } 2668 2669 /* Copy the FrameTemp value to EBP. */ 2670 gen_op_mov_reg_v(s, a_ot, R_EBP, s->T1); 2671 2672 /* Compute the final value of ESP. */ 2673 tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level); 2674 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2675 } 2676 2677 static void gen_leave(DisasContext *s) 2678 { 2679 MemOp d_ot = mo_pushpop(s, s->dflag); 2680 MemOp a_ot = mo_stacksize(s); 2681 2682 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1); 2683 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2684 2685 tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot); 2686 2687 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0); 2688 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2689 } 2690 2691 /* Similarly, except that the assumption here is that we don't decode 2692 the instruction at all -- either a missing opcode, an unimplemented 2693 feature, or just a bogus instruction stream. */ 2694 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) 2695 { 2696 gen_illegal_opcode(s); 2697 2698 if (qemu_loglevel_mask(LOG_UNIMP)) { 2699 FILE *logfile = qemu_log_trylock(); 2700 if (logfile) { 2701 target_ulong pc = s->base.pc_next, end = s->pc; 2702 2703 fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc); 2704 for (; pc < end; ++pc) { 2705 fprintf(logfile, " %02x", cpu_ldub_code(env, pc)); 2706 } 2707 fprintf(logfile, "\n"); 2708 qemu_log_unlock(logfile); 2709 } 2710 } 2711 } 2712 2713 /* an interrupt is different from an exception because of the 2714 privilege checks */ 2715 static void gen_interrupt(DisasContext *s, int intno) 2716 { 2717 gen_update_cc_op(s); 2718 gen_update_eip_cur(s); 2719 gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno), 2720 cur_insn_len_i32(s)); 2721 s->base.is_jmp = DISAS_NORETURN; 2722 } 2723 2724 static void gen_set_hflag(DisasContext *s, uint32_t mask) 2725 { 2726 if ((s->flags & mask) == 0) { 2727 TCGv_i32 t = tcg_temp_new_i32(); 2728 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags)); 2729 tcg_gen_ori_i32(t, t, mask); 2730 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags)); 2731 tcg_temp_free_i32(t); 2732 s->flags |= mask; 2733 } 2734 } 2735 2736 static void gen_reset_hflag(DisasContext *s, uint32_t mask) 2737 { 2738 if (s->flags & mask) { 2739 TCGv_i32 t = tcg_temp_new_i32(); 2740 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags)); 2741 tcg_gen_andi_i32(t, t, ~mask); 2742 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags)); 2743 tcg_temp_free_i32(t); 2744 s->flags &= ~mask; 2745 } 2746 } 2747 2748 /* Clear BND registers during legacy branches. */ 2749 static void gen_bnd_jmp(DisasContext *s) 2750 { 2751 /* Clear the registers only if BND prefix is missing, MPX is enabled, 2752 and if the BNDREGs are known to be in use (non-zero) already. 2753 The helper itself will check BNDPRESERVE at runtime. */ 2754 if ((s->prefix & PREFIX_REPNZ) == 0 2755 && (s->flags & HF_MPX_EN_MASK) != 0 2756 && (s->flags & HF_MPX_IU_MASK) != 0) { 2757 gen_helper_bnd_jmp(cpu_env); 2758 } 2759 } 2760 2761 /* Generate an end of block. Trace exception is also generated if needed. 2762 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. 2763 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of 2764 S->TF. This is used by the syscall/sysret insns. */ 2765 static void 2766 do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr) 2767 { 2768 gen_update_cc_op(s); 2769 2770 /* If several instructions disable interrupts, only the first does it. */ 2771 if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) { 2772 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); 2773 } else { 2774 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); 2775 } 2776 2777 if (s->base.tb->flags & HF_RF_MASK) { 2778 gen_helper_reset_rf(cpu_env); 2779 } 2780 if (recheck_tf) { 2781 gen_helper_rechecking_single_step(cpu_env); 2782 tcg_gen_exit_tb(NULL, 0); 2783 } else if (s->flags & HF_TF_MASK) { 2784 gen_helper_single_step(cpu_env); 2785 } else if (jr) { 2786 tcg_gen_lookup_and_goto_ptr(); 2787 } else { 2788 tcg_gen_exit_tb(NULL, 0); 2789 } 2790 s->base.is_jmp = DISAS_NORETURN; 2791 } 2792 2793 static inline void 2794 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf) 2795 { 2796 do_gen_eob_worker(s, inhibit, recheck_tf, false); 2797 } 2798 2799 /* End of block. 2800 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */ 2801 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit) 2802 { 2803 gen_eob_worker(s, inhibit, false); 2804 } 2805 2806 /* End of block, resetting the inhibit irq flag. */ 2807 static void gen_eob(DisasContext *s) 2808 { 2809 gen_eob_worker(s, false, false); 2810 } 2811 2812 /* Jump to register */ 2813 static void gen_jr(DisasContext *s) 2814 { 2815 do_gen_eob_worker(s, false, false, true); 2816 } 2817 2818 /* Jump to eip+diff, truncating the result to OT. */ 2819 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num) 2820 { 2821 bool use_goto_tb = s->jmp_opt; 2822 target_ulong mask = -1; 2823 target_ulong new_pc = s->pc + diff; 2824 target_ulong new_eip = new_pc - s->cs_base; 2825 2826 /* In 64-bit mode, operand size is fixed at 64 bits. */ 2827 if (!CODE64(s)) { 2828 if (ot == MO_16) { 2829 mask = 0xffff; 2830 if (TARGET_TB_PCREL && CODE32(s)) { 2831 use_goto_tb = false; 2832 } 2833 } else { 2834 mask = 0xffffffff; 2835 } 2836 } 2837 new_eip &= mask; 2838 2839 gen_update_cc_op(s); 2840 set_cc_op(s, CC_OP_DYNAMIC); 2841 2842 if (TARGET_TB_PCREL) { 2843 tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save); 2844 /* 2845 * If we can prove the branch does not leave the page and we have 2846 * no extra masking to apply (data16 branch in code32, see above), 2847 * then we have also proven that the addition does not wrap. 2848 */ 2849 if (!use_goto_tb || !is_same_page(&s->base, new_pc)) { 2850 tcg_gen_andi_tl(cpu_eip, cpu_eip, mask); 2851 use_goto_tb = false; 2852 } 2853 } 2854 2855 if (use_goto_tb && 2856 translator_use_goto_tb(&s->base, new_eip + s->cs_base)) { 2857 /* jump to same page: we can use a direct jump */ 2858 tcg_gen_goto_tb(tb_num); 2859 if (!TARGET_TB_PCREL) { 2860 tcg_gen_movi_tl(cpu_eip, new_eip); 2861 } 2862 tcg_gen_exit_tb(s->base.tb, tb_num); 2863 s->base.is_jmp = DISAS_NORETURN; 2864 } else { 2865 if (!TARGET_TB_PCREL) { 2866 tcg_gen_movi_tl(cpu_eip, new_eip); 2867 } 2868 if (s->jmp_opt) { 2869 gen_jr(s); /* jump to another page */ 2870 } else { 2871 gen_eob(s); /* exit to main loop */ 2872 } 2873 } 2874 } 2875 2876 /* Jump to eip+diff, truncating to the current code size. */ 2877 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num) 2878 { 2879 /* CODE64 ignores the OT argument, so we need not consider it. */ 2880 gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num); 2881 } 2882 2883 static inline void gen_ldq_env_A0(DisasContext *s, int offset) 2884 { 2885 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2886 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset); 2887 } 2888 2889 static inline void gen_stq_env_A0(DisasContext *s, int offset) 2890 { 2891 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset); 2892 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2893 } 2894 2895 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align) 2896 { 2897 int mem_index = s->mem_index; 2898 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index, 2899 MO_LEUQ | (align ? MO_ALIGN_16 : 0)); 2900 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0))); 2901 tcg_gen_addi_tl(s->tmp0, s->A0, 8); 2902 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2903 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1))); 2904 } 2905 2906 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align) 2907 { 2908 int mem_index = s->mem_index; 2909 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0))); 2910 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, 2911 MO_LEUQ | (align ? MO_ALIGN_16 : 0)); 2912 tcg_gen_addi_tl(s->tmp0, s->A0, 8); 2913 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1))); 2914 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2915 } 2916 2917 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align) 2918 { 2919 int mem_index = s->mem_index; 2920 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index, 2921 MO_LEUQ | (align ? MO_ALIGN_32 : 0)); 2922 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(0))); 2923 tcg_gen_addi_tl(s->tmp0, s->A0, 8); 2924 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2925 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(1))); 2926 2927 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2928 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2929 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(2))); 2930 tcg_gen_addi_tl(s->tmp0, s->A0, 24); 2931 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2932 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(3))); 2933 } 2934 2935 static void gen_sty_env_A0(DisasContext *s, int offset, bool align) 2936 { 2937 int mem_index = s->mem_index; 2938 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(0))); 2939 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, 2940 MO_LEUQ | (align ? MO_ALIGN_32 : 0)); 2941 tcg_gen_addi_tl(s->tmp0, s->A0, 8); 2942 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(1))); 2943 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2944 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2945 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(2))); 2946 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2947 tcg_gen_addi_tl(s->tmp0, s->A0, 24); 2948 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(3))); 2949 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2950 } 2951 2952 #include "decode-new.h" 2953 #include "emit.c.inc" 2954 #include "decode-new.c.inc" 2955 2956 /* convert one instruction. s->base.is_jmp is set if the translation must 2957 be stopped. Return the next pc value */ 2958 static bool disas_insn(DisasContext *s, CPUState *cpu) 2959 { 2960 CPUX86State *env = cpu->env_ptr; 2961 int b, prefixes; 2962 int shift; 2963 MemOp ot, aflag, dflag; 2964 int modrm, reg, rm, mod, op, opreg, val; 2965 bool orig_cc_op_dirty = s->cc_op_dirty; 2966 CCOp orig_cc_op = s->cc_op; 2967 target_ulong orig_pc_save = s->pc_save; 2968 2969 s->pc = s->base.pc_next; 2970 s->override = -1; 2971 #ifdef TARGET_X86_64 2972 s->rex_r = 0; 2973 s->rex_x = 0; 2974 s->rex_b = 0; 2975 #endif 2976 s->rip_offset = 0; /* for relative ip address */ 2977 s->vex_l = 0; 2978 s->vex_v = 0; 2979 s->vex_w = false; 2980 switch (sigsetjmp(s->jmpbuf, 0)) { 2981 case 0: 2982 break; 2983 case 1: 2984 gen_exception_gpf(s); 2985 return true; 2986 case 2: 2987 /* Restore state that may affect the next instruction. */ 2988 s->pc = s->base.pc_next; 2989 /* 2990 * TODO: These save/restore can be removed after the table-based 2991 * decoder is complete; we will be decoding the insn completely 2992 * before any code generation that might affect these variables. 2993 */ 2994 s->cc_op_dirty = orig_cc_op_dirty; 2995 s->cc_op = orig_cc_op; 2996 s->pc_save = orig_pc_save; 2997 /* END TODO */ 2998 s->base.num_insns--; 2999 tcg_remove_ops_after(s->prev_insn_end); 3000 s->base.is_jmp = DISAS_TOO_MANY; 3001 return false; 3002 default: 3003 g_assert_not_reached(); 3004 } 3005 3006 prefixes = 0; 3007 3008 next_byte: 3009 s->prefix = prefixes; 3010 b = x86_ldub_code(env, s); 3011 /* Collect prefixes. */ 3012 switch (b) { 3013 default: 3014 break; 3015 case 0x0f: 3016 b = x86_ldub_code(env, s) + 0x100; 3017 break; 3018 case 0xf3: 3019 prefixes |= PREFIX_REPZ; 3020 prefixes &= ~PREFIX_REPNZ; 3021 goto next_byte; 3022 case 0xf2: 3023 prefixes |= PREFIX_REPNZ; 3024 prefixes &= ~PREFIX_REPZ; 3025 goto next_byte; 3026 case 0xf0: 3027 prefixes |= PREFIX_LOCK; 3028 goto next_byte; 3029 case 0x2e: 3030 s->override = R_CS; 3031 goto next_byte; 3032 case 0x36: 3033 s->override = R_SS; 3034 goto next_byte; 3035 case 0x3e: 3036 s->override = R_DS; 3037 goto next_byte; 3038 case 0x26: 3039 s->override = R_ES; 3040 goto next_byte; 3041 case 0x64: 3042 s->override = R_FS; 3043 goto next_byte; 3044 case 0x65: 3045 s->override = R_GS; 3046 goto next_byte; 3047 case 0x66: 3048 prefixes |= PREFIX_DATA; 3049 goto next_byte; 3050 case 0x67: 3051 prefixes |= PREFIX_ADR; 3052 goto next_byte; 3053 #ifdef TARGET_X86_64 3054 case 0x40 ... 0x4f: 3055 if (CODE64(s)) { 3056 /* REX prefix */ 3057 prefixes |= PREFIX_REX; 3058 s->vex_w = (b >> 3) & 1; 3059 s->rex_r = (b & 0x4) << 1; 3060 s->rex_x = (b & 0x2) << 2; 3061 s->rex_b = (b & 0x1) << 3; 3062 goto next_byte; 3063 } 3064 break; 3065 #endif 3066 case 0xc5: /* 2-byte VEX */ 3067 case 0xc4: /* 3-byte VEX */ 3068 if (CODE32(s) && !VM86(s)) { 3069 int vex2 = x86_ldub_code(env, s); 3070 s->pc--; /* rewind the advance_pc() x86_ldub_code() did */ 3071 3072 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) { 3073 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b, 3074 otherwise the instruction is LES or LDS. */ 3075 break; 3076 } 3077 disas_insn_new(s, cpu, b); 3078 return s->pc; 3079 } 3080 break; 3081 } 3082 3083 /* Post-process prefixes. */ 3084 if (CODE64(s)) { 3085 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit 3086 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence 3087 over 0x66 if both are present. */ 3088 dflag = (REX_W(s) ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32); 3089 /* In 64-bit mode, 0x67 selects 32-bit addressing. */ 3090 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64); 3091 } else { 3092 /* In 16/32-bit mode, 0x66 selects the opposite data size. */ 3093 if (CODE32(s) ^ ((prefixes & PREFIX_DATA) != 0)) { 3094 dflag = MO_32; 3095 } else { 3096 dflag = MO_16; 3097 } 3098 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */ 3099 if (CODE32(s) ^ ((prefixes & PREFIX_ADR) != 0)) { 3100 aflag = MO_32; 3101 } else { 3102 aflag = MO_16; 3103 } 3104 } 3105 3106 s->prefix = prefixes; 3107 s->aflag = aflag; 3108 s->dflag = dflag; 3109 3110 /* now check op code */ 3111 switch (b) { 3112 /**************************/ 3113 /* arith & logic */ 3114 case 0x00 ... 0x05: 3115 case 0x08 ... 0x0d: 3116 case 0x10 ... 0x15: 3117 case 0x18 ... 0x1d: 3118 case 0x20 ... 0x25: 3119 case 0x28 ... 0x2d: 3120 case 0x30 ... 0x35: 3121 case 0x38 ... 0x3d: 3122 { 3123 int op, f, val; 3124 op = (b >> 3) & 7; 3125 f = (b >> 1) & 3; 3126 3127 ot = mo_b_d(b, dflag); 3128 3129 switch(f) { 3130 case 0: /* OP Ev, Gv */ 3131 modrm = x86_ldub_code(env, s); 3132 reg = ((modrm >> 3) & 7) | REX_R(s); 3133 mod = (modrm >> 6) & 3; 3134 rm = (modrm & 7) | REX_B(s); 3135 if (mod != 3) { 3136 gen_lea_modrm(env, s, modrm); 3137 opreg = OR_TMP0; 3138 } else if (op == OP_XORL && rm == reg) { 3139 xor_zero: 3140 /* xor reg, reg optimisation */ 3141 set_cc_op(s, CC_OP_CLR); 3142 tcg_gen_movi_tl(s->T0, 0); 3143 gen_op_mov_reg_v(s, ot, reg, s->T0); 3144 break; 3145 } else { 3146 opreg = rm; 3147 } 3148 gen_op_mov_v_reg(s, ot, s->T1, reg); 3149 gen_op(s, op, ot, opreg); 3150 break; 3151 case 1: /* OP Gv, Ev */ 3152 modrm = x86_ldub_code(env, s); 3153 mod = (modrm >> 6) & 3; 3154 reg = ((modrm >> 3) & 7) | REX_R(s); 3155 rm = (modrm & 7) | REX_B(s); 3156 if (mod != 3) { 3157 gen_lea_modrm(env, s, modrm); 3158 gen_op_ld_v(s, ot, s->T1, s->A0); 3159 } else if (op == OP_XORL && rm == reg) { 3160 goto xor_zero; 3161 } else { 3162 gen_op_mov_v_reg(s, ot, s->T1, rm); 3163 } 3164 gen_op(s, op, ot, reg); 3165 break; 3166 case 2: /* OP A, Iv */ 3167 val = insn_get(env, s, ot); 3168 tcg_gen_movi_tl(s->T1, val); 3169 gen_op(s, op, ot, OR_EAX); 3170 break; 3171 } 3172 } 3173 break; 3174 3175 case 0x82: 3176 if (CODE64(s)) 3177 goto illegal_op; 3178 /* fall through */ 3179 case 0x80: /* GRP1 */ 3180 case 0x81: 3181 case 0x83: 3182 { 3183 int val; 3184 3185 ot = mo_b_d(b, dflag); 3186 3187 modrm = x86_ldub_code(env, s); 3188 mod = (modrm >> 6) & 3; 3189 rm = (modrm & 7) | REX_B(s); 3190 op = (modrm >> 3) & 7; 3191 3192 if (mod != 3) { 3193 if (b == 0x83) 3194 s->rip_offset = 1; 3195 else 3196 s->rip_offset = insn_const_size(ot); 3197 gen_lea_modrm(env, s, modrm); 3198 opreg = OR_TMP0; 3199 } else { 3200 opreg = rm; 3201 } 3202 3203 switch(b) { 3204 default: 3205 case 0x80: 3206 case 0x81: 3207 case 0x82: 3208 val = insn_get(env, s, ot); 3209 break; 3210 case 0x83: 3211 val = (int8_t)insn_get(env, s, MO_8); 3212 break; 3213 } 3214 tcg_gen_movi_tl(s->T1, val); 3215 gen_op(s, op, ot, opreg); 3216 } 3217 break; 3218 3219 /**************************/ 3220 /* inc, dec, and other misc arith */ 3221 case 0x40 ... 0x47: /* inc Gv */ 3222 ot = dflag; 3223 gen_inc(s, ot, OR_EAX + (b & 7), 1); 3224 break; 3225 case 0x48 ... 0x4f: /* dec Gv */ 3226 ot = dflag; 3227 gen_inc(s, ot, OR_EAX + (b & 7), -1); 3228 break; 3229 case 0xf6: /* GRP3 */ 3230 case 0xf7: 3231 ot = mo_b_d(b, dflag); 3232 3233 modrm = x86_ldub_code(env, s); 3234 mod = (modrm >> 6) & 3; 3235 rm = (modrm & 7) | REX_B(s); 3236 op = (modrm >> 3) & 7; 3237 if (mod != 3) { 3238 if (op == 0) { 3239 s->rip_offset = insn_const_size(ot); 3240 } 3241 gen_lea_modrm(env, s, modrm); 3242 /* For those below that handle locked memory, don't load here. */ 3243 if (!(s->prefix & PREFIX_LOCK) 3244 || op != 2) { 3245 gen_op_ld_v(s, ot, s->T0, s->A0); 3246 } 3247 } else { 3248 gen_op_mov_v_reg(s, ot, s->T0, rm); 3249 } 3250 3251 switch(op) { 3252 case 0: /* test */ 3253 val = insn_get(env, s, ot); 3254 tcg_gen_movi_tl(s->T1, val); 3255 gen_op_testl_T0_T1_cc(s); 3256 set_cc_op(s, CC_OP_LOGICB + ot); 3257 break; 3258 case 2: /* not */ 3259 if (s->prefix & PREFIX_LOCK) { 3260 if (mod == 3) { 3261 goto illegal_op; 3262 } 3263 tcg_gen_movi_tl(s->T0, ~0); 3264 tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0, 3265 s->mem_index, ot | MO_LE); 3266 } else { 3267 tcg_gen_not_tl(s->T0, s->T0); 3268 if (mod != 3) { 3269 gen_op_st_v(s, ot, s->T0, s->A0); 3270 } else { 3271 gen_op_mov_reg_v(s, ot, rm, s->T0); 3272 } 3273 } 3274 break; 3275 case 3: /* neg */ 3276 if (s->prefix & PREFIX_LOCK) { 3277 TCGLabel *label1; 3278 TCGv a0, t0, t1, t2; 3279 3280 if (mod == 3) { 3281 goto illegal_op; 3282 } 3283 a0 = tcg_temp_local_new(); 3284 t0 = tcg_temp_local_new(); 3285 label1 = gen_new_label(); 3286 3287 tcg_gen_mov_tl(a0, s->A0); 3288 tcg_gen_mov_tl(t0, s->T0); 3289 3290 gen_set_label(label1); 3291 t1 = tcg_temp_new(); 3292 t2 = tcg_temp_new(); 3293 tcg_gen_mov_tl(t2, t0); 3294 tcg_gen_neg_tl(t1, t0); 3295 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1, 3296 s->mem_index, ot | MO_LE); 3297 tcg_temp_free(t1); 3298 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1); 3299 3300 tcg_temp_free(t2); 3301 tcg_temp_free(a0); 3302 tcg_gen_mov_tl(s->T0, t0); 3303 tcg_temp_free(t0); 3304 } else { 3305 tcg_gen_neg_tl(s->T0, s->T0); 3306 if (mod != 3) { 3307 gen_op_st_v(s, ot, s->T0, s->A0); 3308 } else { 3309 gen_op_mov_reg_v(s, ot, rm, s->T0); 3310 } 3311 } 3312 gen_op_update_neg_cc(s); 3313 set_cc_op(s, CC_OP_SUBB + ot); 3314 break; 3315 case 4: /* mul */ 3316 switch(ot) { 3317 case MO_8: 3318 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX); 3319 tcg_gen_ext8u_tl(s->T0, s->T0); 3320 tcg_gen_ext8u_tl(s->T1, s->T1); 3321 /* XXX: use 32 bit mul which could be faster */ 3322 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3323 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3324 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3325 tcg_gen_andi_tl(cpu_cc_src, s->T0, 0xff00); 3326 set_cc_op(s, CC_OP_MULB); 3327 break; 3328 case MO_16: 3329 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX); 3330 tcg_gen_ext16u_tl(s->T0, s->T0); 3331 tcg_gen_ext16u_tl(s->T1, s->T1); 3332 /* XXX: use 32 bit mul which could be faster */ 3333 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3334 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3335 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3336 tcg_gen_shri_tl(s->T0, s->T0, 16); 3337 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); 3338 tcg_gen_mov_tl(cpu_cc_src, s->T0); 3339 set_cc_op(s, CC_OP_MULW); 3340 break; 3341 default: 3342 case MO_32: 3343 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3344 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]); 3345 tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32, 3346 s->tmp2_i32, s->tmp3_i32); 3347 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32); 3348 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32); 3349 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 3350 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]); 3351 set_cc_op(s, CC_OP_MULL); 3352 break; 3353 #ifdef TARGET_X86_64 3354 case MO_64: 3355 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX], 3356 s->T0, cpu_regs[R_EAX]); 3357 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 3358 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]); 3359 set_cc_op(s, CC_OP_MULQ); 3360 break; 3361 #endif 3362 } 3363 break; 3364 case 5: /* imul */ 3365 switch(ot) { 3366 case MO_8: 3367 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX); 3368 tcg_gen_ext8s_tl(s->T0, s->T0); 3369 tcg_gen_ext8s_tl(s->T1, s->T1); 3370 /* XXX: use 32 bit mul which could be faster */ 3371 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3372 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3373 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3374 tcg_gen_ext8s_tl(s->tmp0, s->T0); 3375 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0); 3376 set_cc_op(s, CC_OP_MULB); 3377 break; 3378 case MO_16: 3379 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX); 3380 tcg_gen_ext16s_tl(s->T0, s->T0); 3381 tcg_gen_ext16s_tl(s->T1, s->T1); 3382 /* XXX: use 32 bit mul which could be faster */ 3383 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3384 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3385 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3386 tcg_gen_ext16s_tl(s->tmp0, s->T0); 3387 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0); 3388 tcg_gen_shri_tl(s->T0, s->T0, 16); 3389 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); 3390 set_cc_op(s, CC_OP_MULW); 3391 break; 3392 default: 3393 case MO_32: 3394 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3395 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]); 3396 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32, 3397 s->tmp2_i32, s->tmp3_i32); 3398 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32); 3399 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32); 3400 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31); 3401 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 3402 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32); 3403 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32); 3404 set_cc_op(s, CC_OP_MULL); 3405 break; 3406 #ifdef TARGET_X86_64 3407 case MO_64: 3408 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX], 3409 s->T0, cpu_regs[R_EAX]); 3410 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 3411 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63); 3412 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]); 3413 set_cc_op(s, CC_OP_MULQ); 3414 break; 3415 #endif 3416 } 3417 break; 3418 case 6: /* div */ 3419 switch(ot) { 3420 case MO_8: 3421 gen_helper_divb_AL(cpu_env, s->T0); 3422 break; 3423 case MO_16: 3424 gen_helper_divw_AX(cpu_env, s->T0); 3425 break; 3426 default: 3427 case MO_32: 3428 gen_helper_divl_EAX(cpu_env, s->T0); 3429 break; 3430 #ifdef TARGET_X86_64 3431 case MO_64: 3432 gen_helper_divq_EAX(cpu_env, s->T0); 3433 break; 3434 #endif 3435 } 3436 break; 3437 case 7: /* idiv */ 3438 switch(ot) { 3439 case MO_8: 3440 gen_helper_idivb_AL(cpu_env, s->T0); 3441 break; 3442 case MO_16: 3443 gen_helper_idivw_AX(cpu_env, s->T0); 3444 break; 3445 default: 3446 case MO_32: 3447 gen_helper_idivl_EAX(cpu_env, s->T0); 3448 break; 3449 #ifdef TARGET_X86_64 3450 case MO_64: 3451 gen_helper_idivq_EAX(cpu_env, s->T0); 3452 break; 3453 #endif 3454 } 3455 break; 3456 default: 3457 goto unknown_op; 3458 } 3459 break; 3460 3461 case 0xfe: /* GRP4 */ 3462 case 0xff: /* GRP5 */ 3463 ot = mo_b_d(b, dflag); 3464 3465 modrm = x86_ldub_code(env, s); 3466 mod = (modrm >> 6) & 3; 3467 rm = (modrm & 7) | REX_B(s); 3468 op = (modrm >> 3) & 7; 3469 if (op >= 2 && b == 0xfe) { 3470 goto unknown_op; 3471 } 3472 if (CODE64(s)) { 3473 if (op == 2 || op == 4) { 3474 /* operand size for jumps is 64 bit */ 3475 ot = MO_64; 3476 } else if (op == 3 || op == 5) { 3477 ot = dflag != MO_16 ? MO_32 + REX_W(s) : MO_16; 3478 } else if (op == 6) { 3479 /* default push size is 64 bit */ 3480 ot = mo_pushpop(s, dflag); 3481 } 3482 } 3483 if (mod != 3) { 3484 gen_lea_modrm(env, s, modrm); 3485 if (op >= 2 && op != 3 && op != 5) 3486 gen_op_ld_v(s, ot, s->T0, s->A0); 3487 } else { 3488 gen_op_mov_v_reg(s, ot, s->T0, rm); 3489 } 3490 3491 switch(op) { 3492 case 0: /* inc Ev */ 3493 if (mod != 3) 3494 opreg = OR_TMP0; 3495 else 3496 opreg = rm; 3497 gen_inc(s, ot, opreg, 1); 3498 break; 3499 case 1: /* dec Ev */ 3500 if (mod != 3) 3501 opreg = OR_TMP0; 3502 else 3503 opreg = rm; 3504 gen_inc(s, ot, opreg, -1); 3505 break; 3506 case 2: /* call Ev */ 3507 /* XXX: optimize if memory (no 'and' is necessary) */ 3508 if (dflag == MO_16) { 3509 tcg_gen_ext16u_tl(s->T0, s->T0); 3510 } 3511 gen_push_v(s, eip_next_tl(s)); 3512 gen_op_jmp_v(s, s->T0); 3513 gen_bnd_jmp(s); 3514 s->base.is_jmp = DISAS_JUMP; 3515 break; 3516 case 3: /* lcall Ev */ 3517 if (mod == 3) { 3518 goto illegal_op; 3519 } 3520 gen_op_ld_v(s, ot, s->T1, s->A0); 3521 gen_add_A0_im(s, 1 << ot); 3522 gen_op_ld_v(s, MO_16, s->T0, s->A0); 3523 do_lcall: 3524 if (PE(s) && !VM86(s)) { 3525 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3526 gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1, 3527 tcg_constant_i32(dflag - 1), 3528 eip_next_tl(s)); 3529 } else { 3530 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3531 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 3532 gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32, 3533 tcg_constant_i32(dflag - 1), 3534 eip_next_i32(s)); 3535 } 3536 s->base.is_jmp = DISAS_JUMP; 3537 break; 3538 case 4: /* jmp Ev */ 3539 if (dflag == MO_16) { 3540 tcg_gen_ext16u_tl(s->T0, s->T0); 3541 } 3542 gen_op_jmp_v(s, s->T0); 3543 gen_bnd_jmp(s); 3544 s->base.is_jmp = DISAS_JUMP; 3545 break; 3546 case 5: /* ljmp Ev */ 3547 if (mod == 3) { 3548 goto illegal_op; 3549 } 3550 gen_op_ld_v(s, ot, s->T1, s->A0); 3551 gen_add_A0_im(s, 1 << ot); 3552 gen_op_ld_v(s, MO_16, s->T0, s->A0); 3553 do_ljmp: 3554 if (PE(s) && !VM86(s)) { 3555 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3556 gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1, 3557 eip_next_tl(s)); 3558 } else { 3559 gen_op_movl_seg_T0_vm(s, R_CS); 3560 gen_op_jmp_v(s, s->T1); 3561 } 3562 s->base.is_jmp = DISAS_JUMP; 3563 break; 3564 case 6: /* push Ev */ 3565 gen_push_v(s, s->T0); 3566 break; 3567 default: 3568 goto unknown_op; 3569 } 3570 break; 3571 3572 case 0x84: /* test Ev, Gv */ 3573 case 0x85: 3574 ot = mo_b_d(b, dflag); 3575 3576 modrm = x86_ldub_code(env, s); 3577 reg = ((modrm >> 3) & 7) | REX_R(s); 3578 3579 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3580 gen_op_mov_v_reg(s, ot, s->T1, reg); 3581 gen_op_testl_T0_T1_cc(s); 3582 set_cc_op(s, CC_OP_LOGICB + ot); 3583 break; 3584 3585 case 0xa8: /* test eAX, Iv */ 3586 case 0xa9: 3587 ot = mo_b_d(b, dflag); 3588 val = insn_get(env, s, ot); 3589 3590 gen_op_mov_v_reg(s, ot, s->T0, OR_EAX); 3591 tcg_gen_movi_tl(s->T1, val); 3592 gen_op_testl_T0_T1_cc(s); 3593 set_cc_op(s, CC_OP_LOGICB + ot); 3594 break; 3595 3596 case 0x98: /* CWDE/CBW */ 3597 switch (dflag) { 3598 #ifdef TARGET_X86_64 3599 case MO_64: 3600 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX); 3601 tcg_gen_ext32s_tl(s->T0, s->T0); 3602 gen_op_mov_reg_v(s, MO_64, R_EAX, s->T0); 3603 break; 3604 #endif 3605 case MO_32: 3606 gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX); 3607 tcg_gen_ext16s_tl(s->T0, s->T0); 3608 gen_op_mov_reg_v(s, MO_32, R_EAX, s->T0); 3609 break; 3610 case MO_16: 3611 gen_op_mov_v_reg(s, MO_8, s->T0, R_EAX); 3612 tcg_gen_ext8s_tl(s->T0, s->T0); 3613 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3614 break; 3615 default: 3616 tcg_abort(); 3617 } 3618 break; 3619 case 0x99: /* CDQ/CWD */ 3620 switch (dflag) { 3621 #ifdef TARGET_X86_64 3622 case MO_64: 3623 gen_op_mov_v_reg(s, MO_64, s->T0, R_EAX); 3624 tcg_gen_sari_tl(s->T0, s->T0, 63); 3625 gen_op_mov_reg_v(s, MO_64, R_EDX, s->T0); 3626 break; 3627 #endif 3628 case MO_32: 3629 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX); 3630 tcg_gen_ext32s_tl(s->T0, s->T0); 3631 tcg_gen_sari_tl(s->T0, s->T0, 31); 3632 gen_op_mov_reg_v(s, MO_32, R_EDX, s->T0); 3633 break; 3634 case MO_16: 3635 gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX); 3636 tcg_gen_ext16s_tl(s->T0, s->T0); 3637 tcg_gen_sari_tl(s->T0, s->T0, 15); 3638 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); 3639 break; 3640 default: 3641 tcg_abort(); 3642 } 3643 break; 3644 case 0x1af: /* imul Gv, Ev */ 3645 case 0x69: /* imul Gv, Ev, I */ 3646 case 0x6b: 3647 ot = dflag; 3648 modrm = x86_ldub_code(env, s); 3649 reg = ((modrm >> 3) & 7) | REX_R(s); 3650 if (b == 0x69) 3651 s->rip_offset = insn_const_size(ot); 3652 else if (b == 0x6b) 3653 s->rip_offset = 1; 3654 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3655 if (b == 0x69) { 3656 val = insn_get(env, s, ot); 3657 tcg_gen_movi_tl(s->T1, val); 3658 } else if (b == 0x6b) { 3659 val = (int8_t)insn_get(env, s, MO_8); 3660 tcg_gen_movi_tl(s->T1, val); 3661 } else { 3662 gen_op_mov_v_reg(s, ot, s->T1, reg); 3663 } 3664 switch (ot) { 3665 #ifdef TARGET_X86_64 3666 case MO_64: 3667 tcg_gen_muls2_i64(cpu_regs[reg], s->T1, s->T0, s->T1); 3668 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]); 3669 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63); 3670 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, s->T1); 3671 break; 3672 #endif 3673 case MO_32: 3674 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3675 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 3676 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32, 3677 s->tmp2_i32, s->tmp3_i32); 3678 tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32); 3679 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31); 3680 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]); 3681 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32); 3682 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32); 3683 break; 3684 default: 3685 tcg_gen_ext16s_tl(s->T0, s->T0); 3686 tcg_gen_ext16s_tl(s->T1, s->T1); 3687 /* XXX: use 32 bit mul which could be faster */ 3688 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3689 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3690 tcg_gen_ext16s_tl(s->tmp0, s->T0); 3691 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0); 3692 gen_op_mov_reg_v(s, ot, reg, s->T0); 3693 break; 3694 } 3695 set_cc_op(s, CC_OP_MULB + ot); 3696 break; 3697 case 0x1c0: 3698 case 0x1c1: /* xadd Ev, Gv */ 3699 ot = mo_b_d(b, dflag); 3700 modrm = x86_ldub_code(env, s); 3701 reg = ((modrm >> 3) & 7) | REX_R(s); 3702 mod = (modrm >> 6) & 3; 3703 gen_op_mov_v_reg(s, ot, s->T0, reg); 3704 if (mod == 3) { 3705 rm = (modrm & 7) | REX_B(s); 3706 gen_op_mov_v_reg(s, ot, s->T1, rm); 3707 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3708 gen_op_mov_reg_v(s, ot, reg, s->T1); 3709 gen_op_mov_reg_v(s, ot, rm, s->T0); 3710 } else { 3711 gen_lea_modrm(env, s, modrm); 3712 if (s->prefix & PREFIX_LOCK) { 3713 tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0, 3714 s->mem_index, ot | MO_LE); 3715 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3716 } else { 3717 gen_op_ld_v(s, ot, s->T1, s->A0); 3718 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3719 gen_op_st_v(s, ot, s->T0, s->A0); 3720 } 3721 gen_op_mov_reg_v(s, ot, reg, s->T1); 3722 } 3723 gen_op_update2_cc(s); 3724 set_cc_op(s, CC_OP_ADDB + ot); 3725 break; 3726 case 0x1b0: 3727 case 0x1b1: /* cmpxchg Ev, Gv */ 3728 { 3729 TCGv oldv, newv, cmpv; 3730 3731 ot = mo_b_d(b, dflag); 3732 modrm = x86_ldub_code(env, s); 3733 reg = ((modrm >> 3) & 7) | REX_R(s); 3734 mod = (modrm >> 6) & 3; 3735 oldv = tcg_temp_new(); 3736 newv = tcg_temp_new(); 3737 cmpv = tcg_temp_new(); 3738 gen_op_mov_v_reg(s, ot, newv, reg); 3739 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]); 3740 3741 if (s->prefix & PREFIX_LOCK) { 3742 if (mod == 3) { 3743 goto illegal_op; 3744 } 3745 gen_lea_modrm(env, s, modrm); 3746 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv, 3747 s->mem_index, ot | MO_LE); 3748 gen_op_mov_reg_v(s, ot, R_EAX, oldv); 3749 } else { 3750 if (mod == 3) { 3751 rm = (modrm & 7) | REX_B(s); 3752 gen_op_mov_v_reg(s, ot, oldv, rm); 3753 } else { 3754 gen_lea_modrm(env, s, modrm); 3755 gen_op_ld_v(s, ot, oldv, s->A0); 3756 rm = 0; /* avoid warning */ 3757 } 3758 gen_extu(ot, oldv); 3759 gen_extu(ot, cmpv); 3760 /* store value = (old == cmp ? new : old); */ 3761 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv); 3762 if (mod == 3) { 3763 gen_op_mov_reg_v(s, ot, R_EAX, oldv); 3764 gen_op_mov_reg_v(s, ot, rm, newv); 3765 } else { 3766 /* Perform an unconditional store cycle like physical cpu; 3767 must be before changing accumulator to ensure 3768 idempotency if the store faults and the instruction 3769 is restarted */ 3770 gen_op_st_v(s, ot, newv, s->A0); 3771 gen_op_mov_reg_v(s, ot, R_EAX, oldv); 3772 } 3773 } 3774 tcg_gen_mov_tl(cpu_cc_src, oldv); 3775 tcg_gen_mov_tl(s->cc_srcT, cmpv); 3776 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv); 3777 set_cc_op(s, CC_OP_SUBB + ot); 3778 tcg_temp_free(oldv); 3779 tcg_temp_free(newv); 3780 tcg_temp_free(cmpv); 3781 } 3782 break; 3783 case 0x1c7: /* cmpxchg8b */ 3784 modrm = x86_ldub_code(env, s); 3785 mod = (modrm >> 6) & 3; 3786 switch ((modrm >> 3) & 7) { 3787 case 1: /* CMPXCHG8, CMPXCHG16 */ 3788 if (mod == 3) { 3789 goto illegal_op; 3790 } 3791 #ifdef TARGET_X86_64 3792 if (dflag == MO_64) { 3793 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) { 3794 goto illegal_op; 3795 } 3796 gen_lea_modrm(env, s, modrm); 3797 if ((s->prefix & PREFIX_LOCK) && 3798 (tb_cflags(s->base.tb) & CF_PARALLEL)) { 3799 gen_helper_cmpxchg16b(cpu_env, s->A0); 3800 } else { 3801 gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0); 3802 } 3803 set_cc_op(s, CC_OP_EFLAGS); 3804 break; 3805 } 3806 #endif 3807 if (!(s->cpuid_features & CPUID_CX8)) { 3808 goto illegal_op; 3809 } 3810 gen_lea_modrm(env, s, modrm); 3811 if ((s->prefix & PREFIX_LOCK) && 3812 (tb_cflags(s->base.tb) & CF_PARALLEL)) { 3813 gen_helper_cmpxchg8b(cpu_env, s->A0); 3814 } else { 3815 gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0); 3816 } 3817 set_cc_op(s, CC_OP_EFLAGS); 3818 break; 3819 3820 case 7: /* RDSEED */ 3821 case 6: /* RDRAND */ 3822 if (mod != 3 || 3823 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) || 3824 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { 3825 goto illegal_op; 3826 } 3827 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 3828 gen_io_start(); 3829 s->base.is_jmp = DISAS_TOO_MANY; 3830 } 3831 gen_helper_rdrand(s->T0, cpu_env); 3832 rm = (modrm & 7) | REX_B(s); 3833 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3834 set_cc_op(s, CC_OP_EFLAGS); 3835 break; 3836 3837 default: 3838 goto illegal_op; 3839 } 3840 break; 3841 3842 /**************************/ 3843 /* push/pop */ 3844 case 0x50 ... 0x57: /* push */ 3845 gen_op_mov_v_reg(s, MO_32, s->T0, (b & 7) | REX_B(s)); 3846 gen_push_v(s, s->T0); 3847 break; 3848 case 0x58 ... 0x5f: /* pop */ 3849 ot = gen_pop_T0(s); 3850 /* NOTE: order is important for pop %sp */ 3851 gen_pop_update(s, ot); 3852 gen_op_mov_reg_v(s, ot, (b & 7) | REX_B(s), s->T0); 3853 break; 3854 case 0x60: /* pusha */ 3855 if (CODE64(s)) 3856 goto illegal_op; 3857 gen_pusha(s); 3858 break; 3859 case 0x61: /* popa */ 3860 if (CODE64(s)) 3861 goto illegal_op; 3862 gen_popa(s); 3863 break; 3864 case 0x68: /* push Iv */ 3865 case 0x6a: 3866 ot = mo_pushpop(s, dflag); 3867 if (b == 0x68) 3868 val = insn_get(env, s, ot); 3869 else 3870 val = (int8_t)insn_get(env, s, MO_8); 3871 tcg_gen_movi_tl(s->T0, val); 3872 gen_push_v(s, s->T0); 3873 break; 3874 case 0x8f: /* pop Ev */ 3875 modrm = x86_ldub_code(env, s); 3876 mod = (modrm >> 6) & 3; 3877 ot = gen_pop_T0(s); 3878 if (mod == 3) { 3879 /* NOTE: order is important for pop %sp */ 3880 gen_pop_update(s, ot); 3881 rm = (modrm & 7) | REX_B(s); 3882 gen_op_mov_reg_v(s, ot, rm, s->T0); 3883 } else { 3884 /* NOTE: order is important too for MMU exceptions */ 3885 s->popl_esp_hack = 1 << ot; 3886 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 3887 s->popl_esp_hack = 0; 3888 gen_pop_update(s, ot); 3889 } 3890 break; 3891 case 0xc8: /* enter */ 3892 { 3893 int level; 3894 val = x86_lduw_code(env, s); 3895 level = x86_ldub_code(env, s); 3896 gen_enter(s, val, level); 3897 } 3898 break; 3899 case 0xc9: /* leave */ 3900 gen_leave(s); 3901 break; 3902 case 0x06: /* push es */ 3903 case 0x0e: /* push cs */ 3904 case 0x16: /* push ss */ 3905 case 0x1e: /* push ds */ 3906 if (CODE64(s)) 3907 goto illegal_op; 3908 gen_op_movl_T0_seg(s, b >> 3); 3909 gen_push_v(s, s->T0); 3910 break; 3911 case 0x1a0: /* push fs */ 3912 case 0x1a8: /* push gs */ 3913 gen_op_movl_T0_seg(s, (b >> 3) & 7); 3914 gen_push_v(s, s->T0); 3915 break; 3916 case 0x07: /* pop es */ 3917 case 0x17: /* pop ss */ 3918 case 0x1f: /* pop ds */ 3919 if (CODE64(s)) 3920 goto illegal_op; 3921 reg = b >> 3; 3922 ot = gen_pop_T0(s); 3923 gen_movl_seg_T0(s, reg); 3924 gen_pop_update(s, ot); 3925 break; 3926 case 0x1a1: /* pop fs */ 3927 case 0x1a9: /* pop gs */ 3928 ot = gen_pop_T0(s); 3929 gen_movl_seg_T0(s, (b >> 3) & 7); 3930 gen_pop_update(s, ot); 3931 break; 3932 3933 /**************************/ 3934 /* mov */ 3935 case 0x88: 3936 case 0x89: /* mov Gv, Ev */ 3937 ot = mo_b_d(b, dflag); 3938 modrm = x86_ldub_code(env, s); 3939 reg = ((modrm >> 3) & 7) | REX_R(s); 3940 3941 /* generate a generic store */ 3942 gen_ldst_modrm(env, s, modrm, ot, reg, 1); 3943 break; 3944 case 0xc6: 3945 case 0xc7: /* mov Ev, Iv */ 3946 ot = mo_b_d(b, dflag); 3947 modrm = x86_ldub_code(env, s); 3948 mod = (modrm >> 6) & 3; 3949 if (mod != 3) { 3950 s->rip_offset = insn_const_size(ot); 3951 gen_lea_modrm(env, s, modrm); 3952 } 3953 val = insn_get(env, s, ot); 3954 tcg_gen_movi_tl(s->T0, val); 3955 if (mod != 3) { 3956 gen_op_st_v(s, ot, s->T0, s->A0); 3957 } else { 3958 gen_op_mov_reg_v(s, ot, (modrm & 7) | REX_B(s), s->T0); 3959 } 3960 break; 3961 case 0x8a: 3962 case 0x8b: /* mov Ev, Gv */ 3963 ot = mo_b_d(b, dflag); 3964 modrm = x86_ldub_code(env, s); 3965 reg = ((modrm >> 3) & 7) | REX_R(s); 3966 3967 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3968 gen_op_mov_reg_v(s, ot, reg, s->T0); 3969 break; 3970 case 0x8e: /* mov seg, Gv */ 3971 modrm = x86_ldub_code(env, s); 3972 reg = (modrm >> 3) & 7; 3973 if (reg >= 6 || reg == R_CS) 3974 goto illegal_op; 3975 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3976 gen_movl_seg_T0(s, reg); 3977 break; 3978 case 0x8c: /* mov Gv, seg */ 3979 modrm = x86_ldub_code(env, s); 3980 reg = (modrm >> 3) & 7; 3981 mod = (modrm >> 6) & 3; 3982 if (reg >= 6) 3983 goto illegal_op; 3984 gen_op_movl_T0_seg(s, reg); 3985 ot = mod == 3 ? dflag : MO_16; 3986 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 3987 break; 3988 3989 case 0x1b6: /* movzbS Gv, Eb */ 3990 case 0x1b7: /* movzwS Gv, Eb */ 3991 case 0x1be: /* movsbS Gv, Eb */ 3992 case 0x1bf: /* movswS Gv, Eb */ 3993 { 3994 MemOp d_ot; 3995 MemOp s_ot; 3996 3997 /* d_ot is the size of destination */ 3998 d_ot = dflag; 3999 /* ot is the size of source */ 4000 ot = (b & 1) + MO_8; 4001 /* s_ot is the sign+size of source */ 4002 s_ot = b & 8 ? MO_SIGN | ot : ot; 4003 4004 modrm = x86_ldub_code(env, s); 4005 reg = ((modrm >> 3) & 7) | REX_R(s); 4006 mod = (modrm >> 6) & 3; 4007 rm = (modrm & 7) | REX_B(s); 4008 4009 if (mod == 3) { 4010 if (s_ot == MO_SB && byte_reg_is_xH(s, rm)) { 4011 tcg_gen_sextract_tl(s->T0, cpu_regs[rm - 4], 8, 8); 4012 } else { 4013 gen_op_mov_v_reg(s, ot, s->T0, rm); 4014 switch (s_ot) { 4015 case MO_UB: 4016 tcg_gen_ext8u_tl(s->T0, s->T0); 4017 break; 4018 case MO_SB: 4019 tcg_gen_ext8s_tl(s->T0, s->T0); 4020 break; 4021 case MO_UW: 4022 tcg_gen_ext16u_tl(s->T0, s->T0); 4023 break; 4024 default: 4025 case MO_SW: 4026 tcg_gen_ext16s_tl(s->T0, s->T0); 4027 break; 4028 } 4029 } 4030 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 4031 } else { 4032 gen_lea_modrm(env, s, modrm); 4033 gen_op_ld_v(s, s_ot, s->T0, s->A0); 4034 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 4035 } 4036 } 4037 break; 4038 4039 case 0x8d: /* lea */ 4040 modrm = x86_ldub_code(env, s); 4041 mod = (modrm >> 6) & 3; 4042 if (mod == 3) 4043 goto illegal_op; 4044 reg = ((modrm >> 3) & 7) | REX_R(s); 4045 { 4046 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4047 TCGv ea = gen_lea_modrm_1(s, a, false); 4048 gen_lea_v_seg(s, s->aflag, ea, -1, -1); 4049 gen_op_mov_reg_v(s, dflag, reg, s->A0); 4050 } 4051 break; 4052 4053 case 0xa0: /* mov EAX, Ov */ 4054 case 0xa1: 4055 case 0xa2: /* mov Ov, EAX */ 4056 case 0xa3: 4057 { 4058 target_ulong offset_addr; 4059 4060 ot = mo_b_d(b, dflag); 4061 offset_addr = insn_get_addr(env, s, s->aflag); 4062 tcg_gen_movi_tl(s->A0, offset_addr); 4063 gen_add_A0_ds_seg(s); 4064 if ((b & 2) == 0) { 4065 gen_op_ld_v(s, ot, s->T0, s->A0); 4066 gen_op_mov_reg_v(s, ot, R_EAX, s->T0); 4067 } else { 4068 gen_op_mov_v_reg(s, ot, s->T0, R_EAX); 4069 gen_op_st_v(s, ot, s->T0, s->A0); 4070 } 4071 } 4072 break; 4073 case 0xd7: /* xlat */ 4074 tcg_gen_mov_tl(s->A0, cpu_regs[R_EBX]); 4075 tcg_gen_ext8u_tl(s->T0, cpu_regs[R_EAX]); 4076 tcg_gen_add_tl(s->A0, s->A0, s->T0); 4077 gen_extu(s->aflag, s->A0); 4078 gen_add_A0_ds_seg(s); 4079 gen_op_ld_v(s, MO_8, s->T0, s->A0); 4080 gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0); 4081 break; 4082 case 0xb0 ... 0xb7: /* mov R, Ib */ 4083 val = insn_get(env, s, MO_8); 4084 tcg_gen_movi_tl(s->T0, val); 4085 gen_op_mov_reg_v(s, MO_8, (b & 7) | REX_B(s), s->T0); 4086 break; 4087 case 0xb8 ... 0xbf: /* mov R, Iv */ 4088 #ifdef TARGET_X86_64 4089 if (dflag == MO_64) { 4090 uint64_t tmp; 4091 /* 64 bit case */ 4092 tmp = x86_ldq_code(env, s); 4093 reg = (b & 7) | REX_B(s); 4094 tcg_gen_movi_tl(s->T0, tmp); 4095 gen_op_mov_reg_v(s, MO_64, reg, s->T0); 4096 } else 4097 #endif 4098 { 4099 ot = dflag; 4100 val = insn_get(env, s, ot); 4101 reg = (b & 7) | REX_B(s); 4102 tcg_gen_movi_tl(s->T0, val); 4103 gen_op_mov_reg_v(s, ot, reg, s->T0); 4104 } 4105 break; 4106 4107 case 0x91 ... 0x97: /* xchg R, EAX */ 4108 do_xchg_reg_eax: 4109 ot = dflag; 4110 reg = (b & 7) | REX_B(s); 4111 rm = R_EAX; 4112 goto do_xchg_reg; 4113 case 0x86: 4114 case 0x87: /* xchg Ev, Gv */ 4115 ot = mo_b_d(b, dflag); 4116 modrm = x86_ldub_code(env, s); 4117 reg = ((modrm >> 3) & 7) | REX_R(s); 4118 mod = (modrm >> 6) & 3; 4119 if (mod == 3) { 4120 rm = (modrm & 7) | REX_B(s); 4121 do_xchg_reg: 4122 gen_op_mov_v_reg(s, ot, s->T0, reg); 4123 gen_op_mov_v_reg(s, ot, s->T1, rm); 4124 gen_op_mov_reg_v(s, ot, rm, s->T0); 4125 gen_op_mov_reg_v(s, ot, reg, s->T1); 4126 } else { 4127 gen_lea_modrm(env, s, modrm); 4128 gen_op_mov_v_reg(s, ot, s->T0, reg); 4129 /* for xchg, lock is implicit */ 4130 tcg_gen_atomic_xchg_tl(s->T1, s->A0, s->T0, 4131 s->mem_index, ot | MO_LE); 4132 gen_op_mov_reg_v(s, ot, reg, s->T1); 4133 } 4134 break; 4135 case 0xc4: /* les Gv */ 4136 /* In CODE64 this is VEX3; see above. */ 4137 op = R_ES; 4138 goto do_lxx; 4139 case 0xc5: /* lds Gv */ 4140 /* In CODE64 this is VEX2; see above. */ 4141 op = R_DS; 4142 goto do_lxx; 4143 case 0x1b2: /* lss Gv */ 4144 op = R_SS; 4145 goto do_lxx; 4146 case 0x1b4: /* lfs Gv */ 4147 op = R_FS; 4148 goto do_lxx; 4149 case 0x1b5: /* lgs Gv */ 4150 op = R_GS; 4151 do_lxx: 4152 ot = dflag != MO_16 ? MO_32 : MO_16; 4153 modrm = x86_ldub_code(env, s); 4154 reg = ((modrm >> 3) & 7) | REX_R(s); 4155 mod = (modrm >> 6) & 3; 4156 if (mod == 3) 4157 goto illegal_op; 4158 gen_lea_modrm(env, s, modrm); 4159 gen_op_ld_v(s, ot, s->T1, s->A0); 4160 gen_add_A0_im(s, 1 << ot); 4161 /* load the segment first to handle exceptions properly */ 4162 gen_op_ld_v(s, MO_16, s->T0, s->A0); 4163 gen_movl_seg_T0(s, op); 4164 /* then put the data */ 4165 gen_op_mov_reg_v(s, ot, reg, s->T1); 4166 break; 4167 4168 /************************/ 4169 /* shifts */ 4170 case 0xc0: 4171 case 0xc1: 4172 /* shift Ev,Ib */ 4173 shift = 2; 4174 grp2: 4175 { 4176 ot = mo_b_d(b, dflag); 4177 modrm = x86_ldub_code(env, s); 4178 mod = (modrm >> 6) & 3; 4179 op = (modrm >> 3) & 7; 4180 4181 if (mod != 3) { 4182 if (shift == 2) { 4183 s->rip_offset = 1; 4184 } 4185 gen_lea_modrm(env, s, modrm); 4186 opreg = OR_TMP0; 4187 } else { 4188 opreg = (modrm & 7) | REX_B(s); 4189 } 4190 4191 /* simpler op */ 4192 if (shift == 0) { 4193 gen_shift(s, op, ot, opreg, OR_ECX); 4194 } else { 4195 if (shift == 2) { 4196 shift = x86_ldub_code(env, s); 4197 } 4198 gen_shifti(s, op, ot, opreg, shift); 4199 } 4200 } 4201 break; 4202 case 0xd0: 4203 case 0xd1: 4204 /* shift Ev,1 */ 4205 shift = 1; 4206 goto grp2; 4207 case 0xd2: 4208 case 0xd3: 4209 /* shift Ev,cl */ 4210 shift = 0; 4211 goto grp2; 4212 4213 case 0x1a4: /* shld imm */ 4214 op = 0; 4215 shift = 1; 4216 goto do_shiftd; 4217 case 0x1a5: /* shld cl */ 4218 op = 0; 4219 shift = 0; 4220 goto do_shiftd; 4221 case 0x1ac: /* shrd imm */ 4222 op = 1; 4223 shift = 1; 4224 goto do_shiftd; 4225 case 0x1ad: /* shrd cl */ 4226 op = 1; 4227 shift = 0; 4228 do_shiftd: 4229 ot = dflag; 4230 modrm = x86_ldub_code(env, s); 4231 mod = (modrm >> 6) & 3; 4232 rm = (modrm & 7) | REX_B(s); 4233 reg = ((modrm >> 3) & 7) | REX_R(s); 4234 if (mod != 3) { 4235 gen_lea_modrm(env, s, modrm); 4236 opreg = OR_TMP0; 4237 } else { 4238 opreg = rm; 4239 } 4240 gen_op_mov_v_reg(s, ot, s->T1, reg); 4241 4242 if (shift) { 4243 TCGv imm = tcg_const_tl(x86_ldub_code(env, s)); 4244 gen_shiftd_rm_T1(s, ot, opreg, op, imm); 4245 tcg_temp_free(imm); 4246 } else { 4247 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]); 4248 } 4249 break; 4250 4251 /************************/ 4252 /* floats */ 4253 case 0xd8 ... 0xdf: 4254 { 4255 bool update_fip = true; 4256 4257 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 4258 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 4259 /* XXX: what to do if illegal op ? */ 4260 gen_exception(s, EXCP07_PREX); 4261 break; 4262 } 4263 modrm = x86_ldub_code(env, s); 4264 mod = (modrm >> 6) & 3; 4265 rm = modrm & 7; 4266 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 4267 if (mod != 3) { 4268 /* memory op */ 4269 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4270 TCGv ea = gen_lea_modrm_1(s, a, false); 4271 TCGv last_addr = tcg_temp_new(); 4272 bool update_fdp = true; 4273 4274 tcg_gen_mov_tl(last_addr, ea); 4275 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override); 4276 4277 switch (op) { 4278 case 0x00 ... 0x07: /* fxxxs */ 4279 case 0x10 ... 0x17: /* fixxxl */ 4280 case 0x20 ... 0x27: /* fxxxl */ 4281 case 0x30 ... 0x37: /* fixxx */ 4282 { 4283 int op1; 4284 op1 = op & 7; 4285 4286 switch (op >> 4) { 4287 case 0: 4288 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4289 s->mem_index, MO_LEUL); 4290 gen_helper_flds_FT0(cpu_env, s->tmp2_i32); 4291 break; 4292 case 1: 4293 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4294 s->mem_index, MO_LEUL); 4295 gen_helper_fildl_FT0(cpu_env, s->tmp2_i32); 4296 break; 4297 case 2: 4298 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 4299 s->mem_index, MO_LEUQ); 4300 gen_helper_fldl_FT0(cpu_env, s->tmp1_i64); 4301 break; 4302 case 3: 4303 default: 4304 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4305 s->mem_index, MO_LESW); 4306 gen_helper_fildl_FT0(cpu_env, s->tmp2_i32); 4307 break; 4308 } 4309 4310 gen_helper_fp_arith_ST0_FT0(op1); 4311 if (op1 == 3) { 4312 /* fcomp needs pop */ 4313 gen_helper_fpop(cpu_env); 4314 } 4315 } 4316 break; 4317 case 0x08: /* flds */ 4318 case 0x0a: /* fsts */ 4319 case 0x0b: /* fstps */ 4320 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 4321 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 4322 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 4323 switch (op & 7) { 4324 case 0: 4325 switch (op >> 4) { 4326 case 0: 4327 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4328 s->mem_index, MO_LEUL); 4329 gen_helper_flds_ST0(cpu_env, s->tmp2_i32); 4330 break; 4331 case 1: 4332 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4333 s->mem_index, MO_LEUL); 4334 gen_helper_fildl_ST0(cpu_env, s->tmp2_i32); 4335 break; 4336 case 2: 4337 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 4338 s->mem_index, MO_LEUQ); 4339 gen_helper_fldl_ST0(cpu_env, s->tmp1_i64); 4340 break; 4341 case 3: 4342 default: 4343 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4344 s->mem_index, MO_LESW); 4345 gen_helper_fildl_ST0(cpu_env, s->tmp2_i32); 4346 break; 4347 } 4348 break; 4349 case 1: 4350 /* XXX: the corresponding CPUID bit must be tested ! */ 4351 switch (op >> 4) { 4352 case 1: 4353 gen_helper_fisttl_ST0(s->tmp2_i32, cpu_env); 4354 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4355 s->mem_index, MO_LEUL); 4356 break; 4357 case 2: 4358 gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env); 4359 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 4360 s->mem_index, MO_LEUQ); 4361 break; 4362 case 3: 4363 default: 4364 gen_helper_fistt_ST0(s->tmp2_i32, cpu_env); 4365 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4366 s->mem_index, MO_LEUW); 4367 break; 4368 } 4369 gen_helper_fpop(cpu_env); 4370 break; 4371 default: 4372 switch (op >> 4) { 4373 case 0: 4374 gen_helper_fsts_ST0(s->tmp2_i32, cpu_env); 4375 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4376 s->mem_index, MO_LEUL); 4377 break; 4378 case 1: 4379 gen_helper_fistl_ST0(s->tmp2_i32, cpu_env); 4380 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4381 s->mem_index, MO_LEUL); 4382 break; 4383 case 2: 4384 gen_helper_fstl_ST0(s->tmp1_i64, cpu_env); 4385 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 4386 s->mem_index, MO_LEUQ); 4387 break; 4388 case 3: 4389 default: 4390 gen_helper_fist_ST0(s->tmp2_i32, cpu_env); 4391 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4392 s->mem_index, MO_LEUW); 4393 break; 4394 } 4395 if ((op & 7) == 3) { 4396 gen_helper_fpop(cpu_env); 4397 } 4398 break; 4399 } 4400 break; 4401 case 0x0c: /* fldenv mem */ 4402 gen_helper_fldenv(cpu_env, s->A0, 4403 tcg_const_i32(dflag - 1)); 4404 update_fip = update_fdp = false; 4405 break; 4406 case 0x0d: /* fldcw mem */ 4407 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4408 s->mem_index, MO_LEUW); 4409 gen_helper_fldcw(cpu_env, s->tmp2_i32); 4410 update_fip = update_fdp = false; 4411 break; 4412 case 0x0e: /* fnstenv mem */ 4413 gen_helper_fstenv(cpu_env, s->A0, 4414 tcg_const_i32(dflag - 1)); 4415 update_fip = update_fdp = false; 4416 break; 4417 case 0x0f: /* fnstcw mem */ 4418 gen_helper_fnstcw(s->tmp2_i32, cpu_env); 4419 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4420 s->mem_index, MO_LEUW); 4421 update_fip = update_fdp = false; 4422 break; 4423 case 0x1d: /* fldt mem */ 4424 gen_helper_fldt_ST0(cpu_env, s->A0); 4425 break; 4426 case 0x1f: /* fstpt mem */ 4427 gen_helper_fstt_ST0(cpu_env, s->A0); 4428 gen_helper_fpop(cpu_env); 4429 break; 4430 case 0x2c: /* frstor mem */ 4431 gen_helper_frstor(cpu_env, s->A0, 4432 tcg_const_i32(dflag - 1)); 4433 update_fip = update_fdp = false; 4434 break; 4435 case 0x2e: /* fnsave mem */ 4436 gen_helper_fsave(cpu_env, s->A0, 4437 tcg_const_i32(dflag - 1)); 4438 update_fip = update_fdp = false; 4439 break; 4440 case 0x2f: /* fnstsw mem */ 4441 gen_helper_fnstsw(s->tmp2_i32, cpu_env); 4442 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4443 s->mem_index, MO_LEUW); 4444 update_fip = update_fdp = false; 4445 break; 4446 case 0x3c: /* fbld */ 4447 gen_helper_fbld_ST0(cpu_env, s->A0); 4448 break; 4449 case 0x3e: /* fbstp */ 4450 gen_helper_fbst_ST0(cpu_env, s->A0); 4451 gen_helper_fpop(cpu_env); 4452 break; 4453 case 0x3d: /* fildll */ 4454 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 4455 s->mem_index, MO_LEUQ); 4456 gen_helper_fildll_ST0(cpu_env, s->tmp1_i64); 4457 break; 4458 case 0x3f: /* fistpll */ 4459 gen_helper_fistll_ST0(s->tmp1_i64, cpu_env); 4460 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 4461 s->mem_index, MO_LEUQ); 4462 gen_helper_fpop(cpu_env); 4463 break; 4464 default: 4465 goto unknown_op; 4466 } 4467 4468 if (update_fdp) { 4469 int last_seg = s->override >= 0 ? s->override : a.def_seg; 4470 4471 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, 4472 offsetof(CPUX86State, 4473 segs[last_seg].selector)); 4474 tcg_gen_st16_i32(s->tmp2_i32, cpu_env, 4475 offsetof(CPUX86State, fpds)); 4476 tcg_gen_st_tl(last_addr, cpu_env, 4477 offsetof(CPUX86State, fpdp)); 4478 } 4479 tcg_temp_free(last_addr); 4480 } else { 4481 /* register float ops */ 4482 opreg = rm; 4483 4484 switch (op) { 4485 case 0x08: /* fld sti */ 4486 gen_helper_fpush(cpu_env); 4487 gen_helper_fmov_ST0_STN(cpu_env, 4488 tcg_const_i32((opreg + 1) & 7)); 4489 break; 4490 case 0x09: /* fxchg sti */ 4491 case 0x29: /* fxchg4 sti, undocumented op */ 4492 case 0x39: /* fxchg7 sti, undocumented op */ 4493 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg)); 4494 break; 4495 case 0x0a: /* grp d9/2 */ 4496 switch (rm) { 4497 case 0: /* fnop */ 4498 /* check exceptions (FreeBSD FPU probe) */ 4499 gen_helper_fwait(cpu_env); 4500 update_fip = false; 4501 break; 4502 default: 4503 goto unknown_op; 4504 } 4505 break; 4506 case 0x0c: /* grp d9/4 */ 4507 switch (rm) { 4508 case 0: /* fchs */ 4509 gen_helper_fchs_ST0(cpu_env); 4510 break; 4511 case 1: /* fabs */ 4512 gen_helper_fabs_ST0(cpu_env); 4513 break; 4514 case 4: /* ftst */ 4515 gen_helper_fldz_FT0(cpu_env); 4516 gen_helper_fcom_ST0_FT0(cpu_env); 4517 break; 4518 case 5: /* fxam */ 4519 gen_helper_fxam_ST0(cpu_env); 4520 break; 4521 default: 4522 goto unknown_op; 4523 } 4524 break; 4525 case 0x0d: /* grp d9/5 */ 4526 { 4527 switch (rm) { 4528 case 0: 4529 gen_helper_fpush(cpu_env); 4530 gen_helper_fld1_ST0(cpu_env); 4531 break; 4532 case 1: 4533 gen_helper_fpush(cpu_env); 4534 gen_helper_fldl2t_ST0(cpu_env); 4535 break; 4536 case 2: 4537 gen_helper_fpush(cpu_env); 4538 gen_helper_fldl2e_ST0(cpu_env); 4539 break; 4540 case 3: 4541 gen_helper_fpush(cpu_env); 4542 gen_helper_fldpi_ST0(cpu_env); 4543 break; 4544 case 4: 4545 gen_helper_fpush(cpu_env); 4546 gen_helper_fldlg2_ST0(cpu_env); 4547 break; 4548 case 5: 4549 gen_helper_fpush(cpu_env); 4550 gen_helper_fldln2_ST0(cpu_env); 4551 break; 4552 case 6: 4553 gen_helper_fpush(cpu_env); 4554 gen_helper_fldz_ST0(cpu_env); 4555 break; 4556 default: 4557 goto unknown_op; 4558 } 4559 } 4560 break; 4561 case 0x0e: /* grp d9/6 */ 4562 switch (rm) { 4563 case 0: /* f2xm1 */ 4564 gen_helper_f2xm1(cpu_env); 4565 break; 4566 case 1: /* fyl2x */ 4567 gen_helper_fyl2x(cpu_env); 4568 break; 4569 case 2: /* fptan */ 4570 gen_helper_fptan(cpu_env); 4571 break; 4572 case 3: /* fpatan */ 4573 gen_helper_fpatan(cpu_env); 4574 break; 4575 case 4: /* fxtract */ 4576 gen_helper_fxtract(cpu_env); 4577 break; 4578 case 5: /* fprem1 */ 4579 gen_helper_fprem1(cpu_env); 4580 break; 4581 case 6: /* fdecstp */ 4582 gen_helper_fdecstp(cpu_env); 4583 break; 4584 default: 4585 case 7: /* fincstp */ 4586 gen_helper_fincstp(cpu_env); 4587 break; 4588 } 4589 break; 4590 case 0x0f: /* grp d9/7 */ 4591 switch (rm) { 4592 case 0: /* fprem */ 4593 gen_helper_fprem(cpu_env); 4594 break; 4595 case 1: /* fyl2xp1 */ 4596 gen_helper_fyl2xp1(cpu_env); 4597 break; 4598 case 2: /* fsqrt */ 4599 gen_helper_fsqrt(cpu_env); 4600 break; 4601 case 3: /* fsincos */ 4602 gen_helper_fsincos(cpu_env); 4603 break; 4604 case 5: /* fscale */ 4605 gen_helper_fscale(cpu_env); 4606 break; 4607 case 4: /* frndint */ 4608 gen_helper_frndint(cpu_env); 4609 break; 4610 case 6: /* fsin */ 4611 gen_helper_fsin(cpu_env); 4612 break; 4613 default: 4614 case 7: /* fcos */ 4615 gen_helper_fcos(cpu_env); 4616 break; 4617 } 4618 break; 4619 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 4620 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 4621 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 4622 { 4623 int op1; 4624 4625 op1 = op & 7; 4626 if (op >= 0x20) { 4627 gen_helper_fp_arith_STN_ST0(op1, opreg); 4628 if (op >= 0x30) { 4629 gen_helper_fpop(cpu_env); 4630 } 4631 } else { 4632 gen_helper_fmov_FT0_STN(cpu_env, 4633 tcg_const_i32(opreg)); 4634 gen_helper_fp_arith_ST0_FT0(op1); 4635 } 4636 } 4637 break; 4638 case 0x02: /* fcom */ 4639 case 0x22: /* fcom2, undocumented op */ 4640 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4641 gen_helper_fcom_ST0_FT0(cpu_env); 4642 break; 4643 case 0x03: /* fcomp */ 4644 case 0x23: /* fcomp3, undocumented op */ 4645 case 0x32: /* fcomp5, undocumented op */ 4646 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4647 gen_helper_fcom_ST0_FT0(cpu_env); 4648 gen_helper_fpop(cpu_env); 4649 break; 4650 case 0x15: /* da/5 */ 4651 switch (rm) { 4652 case 1: /* fucompp */ 4653 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1)); 4654 gen_helper_fucom_ST0_FT0(cpu_env); 4655 gen_helper_fpop(cpu_env); 4656 gen_helper_fpop(cpu_env); 4657 break; 4658 default: 4659 goto unknown_op; 4660 } 4661 break; 4662 case 0x1c: 4663 switch (rm) { 4664 case 0: /* feni (287 only, just do nop here) */ 4665 break; 4666 case 1: /* fdisi (287 only, just do nop here) */ 4667 break; 4668 case 2: /* fclex */ 4669 gen_helper_fclex(cpu_env); 4670 update_fip = false; 4671 break; 4672 case 3: /* fninit */ 4673 gen_helper_fninit(cpu_env); 4674 update_fip = false; 4675 break; 4676 case 4: /* fsetpm (287 only, just do nop here) */ 4677 break; 4678 default: 4679 goto unknown_op; 4680 } 4681 break; 4682 case 0x1d: /* fucomi */ 4683 if (!(s->cpuid_features & CPUID_CMOV)) { 4684 goto illegal_op; 4685 } 4686 gen_update_cc_op(s); 4687 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4688 gen_helper_fucomi_ST0_FT0(cpu_env); 4689 set_cc_op(s, CC_OP_EFLAGS); 4690 break; 4691 case 0x1e: /* fcomi */ 4692 if (!(s->cpuid_features & CPUID_CMOV)) { 4693 goto illegal_op; 4694 } 4695 gen_update_cc_op(s); 4696 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4697 gen_helper_fcomi_ST0_FT0(cpu_env); 4698 set_cc_op(s, CC_OP_EFLAGS); 4699 break; 4700 case 0x28: /* ffree sti */ 4701 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg)); 4702 break; 4703 case 0x2a: /* fst sti */ 4704 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg)); 4705 break; 4706 case 0x2b: /* fstp sti */ 4707 case 0x0b: /* fstp1 sti, undocumented op */ 4708 case 0x3a: /* fstp8 sti, undocumented op */ 4709 case 0x3b: /* fstp9 sti, undocumented op */ 4710 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg)); 4711 gen_helper_fpop(cpu_env); 4712 break; 4713 case 0x2c: /* fucom st(i) */ 4714 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4715 gen_helper_fucom_ST0_FT0(cpu_env); 4716 break; 4717 case 0x2d: /* fucomp st(i) */ 4718 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4719 gen_helper_fucom_ST0_FT0(cpu_env); 4720 gen_helper_fpop(cpu_env); 4721 break; 4722 case 0x33: /* de/3 */ 4723 switch (rm) { 4724 case 1: /* fcompp */ 4725 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1)); 4726 gen_helper_fcom_ST0_FT0(cpu_env); 4727 gen_helper_fpop(cpu_env); 4728 gen_helper_fpop(cpu_env); 4729 break; 4730 default: 4731 goto unknown_op; 4732 } 4733 break; 4734 case 0x38: /* ffreep sti, undocumented op */ 4735 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg)); 4736 gen_helper_fpop(cpu_env); 4737 break; 4738 case 0x3c: /* df/4 */ 4739 switch (rm) { 4740 case 0: 4741 gen_helper_fnstsw(s->tmp2_i32, cpu_env); 4742 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 4743 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 4744 break; 4745 default: 4746 goto unknown_op; 4747 } 4748 break; 4749 case 0x3d: /* fucomip */ 4750 if (!(s->cpuid_features & CPUID_CMOV)) { 4751 goto illegal_op; 4752 } 4753 gen_update_cc_op(s); 4754 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4755 gen_helper_fucomi_ST0_FT0(cpu_env); 4756 gen_helper_fpop(cpu_env); 4757 set_cc_op(s, CC_OP_EFLAGS); 4758 break; 4759 case 0x3e: /* fcomip */ 4760 if (!(s->cpuid_features & CPUID_CMOV)) { 4761 goto illegal_op; 4762 } 4763 gen_update_cc_op(s); 4764 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4765 gen_helper_fcomi_ST0_FT0(cpu_env); 4766 gen_helper_fpop(cpu_env); 4767 set_cc_op(s, CC_OP_EFLAGS); 4768 break; 4769 case 0x10 ... 0x13: /* fcmovxx */ 4770 case 0x18 ... 0x1b: 4771 { 4772 int op1; 4773 TCGLabel *l1; 4774 static const uint8_t fcmov_cc[8] = { 4775 (JCC_B << 1), 4776 (JCC_Z << 1), 4777 (JCC_BE << 1), 4778 (JCC_P << 1), 4779 }; 4780 4781 if (!(s->cpuid_features & CPUID_CMOV)) { 4782 goto illegal_op; 4783 } 4784 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 4785 l1 = gen_new_label(); 4786 gen_jcc1_noeob(s, op1, l1); 4787 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg)); 4788 gen_set_label(l1); 4789 } 4790 break; 4791 default: 4792 goto unknown_op; 4793 } 4794 } 4795 4796 if (update_fip) { 4797 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, 4798 offsetof(CPUX86State, segs[R_CS].selector)); 4799 tcg_gen_st16_i32(s->tmp2_i32, cpu_env, 4800 offsetof(CPUX86State, fpcs)); 4801 tcg_gen_st_tl(eip_cur_tl(s), 4802 cpu_env, offsetof(CPUX86State, fpip)); 4803 } 4804 } 4805 break; 4806 /************************/ 4807 /* string ops */ 4808 4809 case 0xa4: /* movsS */ 4810 case 0xa5: 4811 ot = mo_b_d(b, dflag); 4812 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4813 gen_repz_movs(s, ot); 4814 } else { 4815 gen_movs(s, ot); 4816 } 4817 break; 4818 4819 case 0xaa: /* stosS */ 4820 case 0xab: 4821 ot = mo_b_d(b, dflag); 4822 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4823 gen_repz_stos(s, ot); 4824 } else { 4825 gen_stos(s, ot); 4826 } 4827 break; 4828 case 0xac: /* lodsS */ 4829 case 0xad: 4830 ot = mo_b_d(b, dflag); 4831 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4832 gen_repz_lods(s, ot); 4833 } else { 4834 gen_lods(s, ot); 4835 } 4836 break; 4837 case 0xae: /* scasS */ 4838 case 0xaf: 4839 ot = mo_b_d(b, dflag); 4840 if (prefixes & PREFIX_REPNZ) { 4841 gen_repz_scas(s, ot, 1); 4842 } else if (prefixes & PREFIX_REPZ) { 4843 gen_repz_scas(s, ot, 0); 4844 } else { 4845 gen_scas(s, ot); 4846 } 4847 break; 4848 4849 case 0xa6: /* cmpsS */ 4850 case 0xa7: 4851 ot = mo_b_d(b, dflag); 4852 if (prefixes & PREFIX_REPNZ) { 4853 gen_repz_cmps(s, ot, 1); 4854 } else if (prefixes & PREFIX_REPZ) { 4855 gen_repz_cmps(s, ot, 0); 4856 } else { 4857 gen_cmps(s, ot); 4858 } 4859 break; 4860 case 0x6c: /* insS */ 4861 case 0x6d: 4862 ot = mo_b_d32(b, dflag); 4863 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 4864 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 4865 if (!gen_check_io(s, ot, s->tmp2_i32, 4866 SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) { 4867 break; 4868 } 4869 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4870 gen_io_start(); 4871 s->base.is_jmp = DISAS_TOO_MANY; 4872 } 4873 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4874 gen_repz_ins(s, ot); 4875 } else { 4876 gen_ins(s, ot); 4877 } 4878 break; 4879 case 0x6e: /* outsS */ 4880 case 0x6f: 4881 ot = mo_b_d32(b, dflag); 4882 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 4883 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 4884 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) { 4885 break; 4886 } 4887 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4888 gen_io_start(); 4889 s->base.is_jmp = DISAS_TOO_MANY; 4890 } 4891 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4892 gen_repz_outs(s, ot); 4893 } else { 4894 gen_outs(s, ot); 4895 } 4896 break; 4897 4898 /************************/ 4899 /* port I/O */ 4900 4901 case 0xe4: 4902 case 0xe5: 4903 ot = mo_b_d32(b, dflag); 4904 val = x86_ldub_code(env, s); 4905 tcg_gen_movi_i32(s->tmp2_i32, val); 4906 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) { 4907 break; 4908 } 4909 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4910 gen_io_start(); 4911 s->base.is_jmp = DISAS_TOO_MANY; 4912 } 4913 gen_helper_in_func(ot, s->T1, s->tmp2_i32); 4914 gen_op_mov_reg_v(s, ot, R_EAX, s->T1); 4915 gen_bpt_io(s, s->tmp2_i32, ot); 4916 break; 4917 case 0xe6: 4918 case 0xe7: 4919 ot = mo_b_d32(b, dflag); 4920 val = x86_ldub_code(env, s); 4921 tcg_gen_movi_i32(s->tmp2_i32, val); 4922 if (!gen_check_io(s, ot, s->tmp2_i32, 0)) { 4923 break; 4924 } 4925 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4926 gen_io_start(); 4927 s->base.is_jmp = DISAS_TOO_MANY; 4928 } 4929 gen_op_mov_v_reg(s, ot, s->T1, R_EAX); 4930 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 4931 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 4932 gen_bpt_io(s, s->tmp2_i32, ot); 4933 break; 4934 case 0xec: 4935 case 0xed: 4936 ot = mo_b_d32(b, dflag); 4937 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 4938 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 4939 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) { 4940 break; 4941 } 4942 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4943 gen_io_start(); 4944 s->base.is_jmp = DISAS_TOO_MANY; 4945 } 4946 gen_helper_in_func(ot, s->T1, s->tmp2_i32); 4947 gen_op_mov_reg_v(s, ot, R_EAX, s->T1); 4948 gen_bpt_io(s, s->tmp2_i32, ot); 4949 break; 4950 case 0xee: 4951 case 0xef: 4952 ot = mo_b_d32(b, dflag); 4953 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 4954 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 4955 if (!gen_check_io(s, ot, s->tmp2_i32, 0)) { 4956 break; 4957 } 4958 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4959 gen_io_start(); 4960 s->base.is_jmp = DISAS_TOO_MANY; 4961 } 4962 gen_op_mov_v_reg(s, ot, s->T1, R_EAX); 4963 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 4964 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 4965 gen_bpt_io(s, s->tmp2_i32, ot); 4966 break; 4967 4968 /************************/ 4969 /* control */ 4970 case 0xc2: /* ret im */ 4971 val = x86_ldsw_code(env, s); 4972 ot = gen_pop_T0(s); 4973 gen_stack_update(s, val + (1 << ot)); 4974 /* Note that gen_pop_T0 uses a zero-extending load. */ 4975 gen_op_jmp_v(s, s->T0); 4976 gen_bnd_jmp(s); 4977 s->base.is_jmp = DISAS_JUMP; 4978 break; 4979 case 0xc3: /* ret */ 4980 ot = gen_pop_T0(s); 4981 gen_pop_update(s, ot); 4982 /* Note that gen_pop_T0 uses a zero-extending load. */ 4983 gen_op_jmp_v(s, s->T0); 4984 gen_bnd_jmp(s); 4985 s->base.is_jmp = DISAS_JUMP; 4986 break; 4987 case 0xca: /* lret im */ 4988 val = x86_ldsw_code(env, s); 4989 do_lret: 4990 if (PE(s) && !VM86(s)) { 4991 gen_update_cc_op(s); 4992 gen_update_eip_cur(s); 4993 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1), 4994 tcg_const_i32(val)); 4995 } else { 4996 gen_stack_A0(s); 4997 /* pop offset */ 4998 gen_op_ld_v(s, dflag, s->T0, s->A0); 4999 /* NOTE: keeping EIP updated is not a problem in case of 5000 exception */ 5001 gen_op_jmp_v(s, s->T0); 5002 /* pop selector */ 5003 gen_add_A0_im(s, 1 << dflag); 5004 gen_op_ld_v(s, dflag, s->T0, s->A0); 5005 gen_op_movl_seg_T0_vm(s, R_CS); 5006 /* add stack offset */ 5007 gen_stack_update(s, val + (2 << dflag)); 5008 } 5009 s->base.is_jmp = DISAS_EOB_ONLY; 5010 break; 5011 case 0xcb: /* lret */ 5012 val = 0; 5013 goto do_lret; 5014 case 0xcf: /* iret */ 5015 gen_svm_check_intercept(s, SVM_EXIT_IRET); 5016 if (!PE(s) || VM86(s)) { 5017 /* real mode or vm86 mode */ 5018 if (!check_vm86_iopl(s)) { 5019 break; 5020 } 5021 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1)); 5022 } else { 5023 gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1), 5024 eip_next_i32(s)); 5025 } 5026 set_cc_op(s, CC_OP_EFLAGS); 5027 s->base.is_jmp = DISAS_EOB_ONLY; 5028 break; 5029 case 0xe8: /* call im */ 5030 { 5031 int diff = (dflag != MO_16 5032 ? (int32_t)insn_get(env, s, MO_32) 5033 : (int16_t)insn_get(env, s, MO_16)); 5034 gen_push_v(s, eip_next_tl(s)); 5035 gen_bnd_jmp(s); 5036 gen_jmp_rel(s, dflag, diff, 0); 5037 } 5038 break; 5039 case 0x9a: /* lcall im */ 5040 { 5041 unsigned int selector, offset; 5042 5043 if (CODE64(s)) 5044 goto illegal_op; 5045 ot = dflag; 5046 offset = insn_get(env, s, ot); 5047 selector = insn_get(env, s, MO_16); 5048 5049 tcg_gen_movi_tl(s->T0, selector); 5050 tcg_gen_movi_tl(s->T1, offset); 5051 } 5052 goto do_lcall; 5053 case 0xe9: /* jmp im */ 5054 { 5055 int diff = (dflag != MO_16 5056 ? (int32_t)insn_get(env, s, MO_32) 5057 : (int16_t)insn_get(env, s, MO_16)); 5058 gen_bnd_jmp(s); 5059 gen_jmp_rel(s, dflag, diff, 0); 5060 } 5061 break; 5062 case 0xea: /* ljmp im */ 5063 { 5064 unsigned int selector, offset; 5065 5066 if (CODE64(s)) 5067 goto illegal_op; 5068 ot = dflag; 5069 offset = insn_get(env, s, ot); 5070 selector = insn_get(env, s, MO_16); 5071 5072 tcg_gen_movi_tl(s->T0, selector); 5073 tcg_gen_movi_tl(s->T1, offset); 5074 } 5075 goto do_ljmp; 5076 case 0xeb: /* jmp Jb */ 5077 { 5078 int diff = (int8_t)insn_get(env, s, MO_8); 5079 gen_jmp_rel(s, dflag, diff, 0); 5080 } 5081 break; 5082 case 0x70 ... 0x7f: /* jcc Jb */ 5083 { 5084 int diff = (int8_t)insn_get(env, s, MO_8); 5085 gen_bnd_jmp(s); 5086 gen_jcc(s, b, diff); 5087 } 5088 break; 5089 case 0x180 ... 0x18f: /* jcc Jv */ 5090 { 5091 int diff = (dflag != MO_16 5092 ? (int32_t)insn_get(env, s, MO_32) 5093 : (int16_t)insn_get(env, s, MO_16)); 5094 gen_bnd_jmp(s); 5095 gen_jcc(s, b, diff); 5096 } 5097 break; 5098 5099 case 0x190 ... 0x19f: /* setcc Gv */ 5100 modrm = x86_ldub_code(env, s); 5101 gen_setcc1(s, b, s->T0); 5102 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1); 5103 break; 5104 case 0x140 ... 0x14f: /* cmov Gv, Ev */ 5105 if (!(s->cpuid_features & CPUID_CMOV)) { 5106 goto illegal_op; 5107 } 5108 ot = dflag; 5109 modrm = x86_ldub_code(env, s); 5110 reg = ((modrm >> 3) & 7) | REX_R(s); 5111 gen_cmovcc1(env, s, ot, b, modrm, reg); 5112 break; 5113 5114 /************************/ 5115 /* flags */ 5116 case 0x9c: /* pushf */ 5117 gen_svm_check_intercept(s, SVM_EXIT_PUSHF); 5118 if (check_vm86_iopl(s)) { 5119 gen_update_cc_op(s); 5120 gen_helper_read_eflags(s->T0, cpu_env); 5121 gen_push_v(s, s->T0); 5122 } 5123 break; 5124 case 0x9d: /* popf */ 5125 gen_svm_check_intercept(s, SVM_EXIT_POPF); 5126 if (check_vm86_iopl(s)) { 5127 ot = gen_pop_T0(s); 5128 if (CPL(s) == 0) { 5129 if (dflag != MO_16) { 5130 gen_helper_write_eflags(cpu_env, s->T0, 5131 tcg_const_i32((TF_MASK | AC_MASK | 5132 ID_MASK | NT_MASK | 5133 IF_MASK | 5134 IOPL_MASK))); 5135 } else { 5136 gen_helper_write_eflags(cpu_env, s->T0, 5137 tcg_const_i32((TF_MASK | AC_MASK | 5138 ID_MASK | NT_MASK | 5139 IF_MASK | IOPL_MASK) 5140 & 0xffff)); 5141 } 5142 } else { 5143 if (CPL(s) <= IOPL(s)) { 5144 if (dflag != MO_16) { 5145 gen_helper_write_eflags(cpu_env, s->T0, 5146 tcg_const_i32((TF_MASK | 5147 AC_MASK | 5148 ID_MASK | 5149 NT_MASK | 5150 IF_MASK))); 5151 } else { 5152 gen_helper_write_eflags(cpu_env, s->T0, 5153 tcg_const_i32((TF_MASK | 5154 AC_MASK | 5155 ID_MASK | 5156 NT_MASK | 5157 IF_MASK) 5158 & 0xffff)); 5159 } 5160 } else { 5161 if (dflag != MO_16) { 5162 gen_helper_write_eflags(cpu_env, s->T0, 5163 tcg_const_i32((TF_MASK | AC_MASK | 5164 ID_MASK | NT_MASK))); 5165 } else { 5166 gen_helper_write_eflags(cpu_env, s->T0, 5167 tcg_const_i32((TF_MASK | AC_MASK | 5168 ID_MASK | NT_MASK) 5169 & 0xffff)); 5170 } 5171 } 5172 } 5173 gen_pop_update(s, ot); 5174 set_cc_op(s, CC_OP_EFLAGS); 5175 /* abort translation because TF/AC flag may change */ 5176 s->base.is_jmp = DISAS_EOB_NEXT; 5177 } 5178 break; 5179 case 0x9e: /* sahf */ 5180 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) 5181 goto illegal_op; 5182 gen_op_mov_v_reg(s, MO_8, s->T0, R_AH); 5183 gen_compute_eflags(s); 5184 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O); 5185 tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C); 5186 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0); 5187 break; 5188 case 0x9f: /* lahf */ 5189 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) 5190 goto illegal_op; 5191 gen_compute_eflags(s); 5192 /* Note: gen_compute_eflags() only gives the condition codes */ 5193 tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02); 5194 gen_op_mov_reg_v(s, MO_8, R_AH, s->T0); 5195 break; 5196 case 0xf5: /* cmc */ 5197 gen_compute_eflags(s); 5198 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C); 5199 break; 5200 case 0xf8: /* clc */ 5201 gen_compute_eflags(s); 5202 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C); 5203 break; 5204 case 0xf9: /* stc */ 5205 gen_compute_eflags(s); 5206 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C); 5207 break; 5208 case 0xfc: /* cld */ 5209 tcg_gen_movi_i32(s->tmp2_i32, 1); 5210 tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df)); 5211 break; 5212 case 0xfd: /* std */ 5213 tcg_gen_movi_i32(s->tmp2_i32, -1); 5214 tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df)); 5215 break; 5216 5217 /************************/ 5218 /* bit operations */ 5219 case 0x1ba: /* bt/bts/btr/btc Gv, im */ 5220 ot = dflag; 5221 modrm = x86_ldub_code(env, s); 5222 op = (modrm >> 3) & 7; 5223 mod = (modrm >> 6) & 3; 5224 rm = (modrm & 7) | REX_B(s); 5225 if (mod != 3) { 5226 s->rip_offset = 1; 5227 gen_lea_modrm(env, s, modrm); 5228 if (!(s->prefix & PREFIX_LOCK)) { 5229 gen_op_ld_v(s, ot, s->T0, s->A0); 5230 } 5231 } else { 5232 gen_op_mov_v_reg(s, ot, s->T0, rm); 5233 } 5234 /* load shift */ 5235 val = x86_ldub_code(env, s); 5236 tcg_gen_movi_tl(s->T1, val); 5237 if (op < 4) 5238 goto unknown_op; 5239 op -= 4; 5240 goto bt_op; 5241 case 0x1a3: /* bt Gv, Ev */ 5242 op = 0; 5243 goto do_btx; 5244 case 0x1ab: /* bts */ 5245 op = 1; 5246 goto do_btx; 5247 case 0x1b3: /* btr */ 5248 op = 2; 5249 goto do_btx; 5250 case 0x1bb: /* btc */ 5251 op = 3; 5252 do_btx: 5253 ot = dflag; 5254 modrm = x86_ldub_code(env, s); 5255 reg = ((modrm >> 3) & 7) | REX_R(s); 5256 mod = (modrm >> 6) & 3; 5257 rm = (modrm & 7) | REX_B(s); 5258 gen_op_mov_v_reg(s, MO_32, s->T1, reg); 5259 if (mod != 3) { 5260 AddressParts a = gen_lea_modrm_0(env, s, modrm); 5261 /* specific case: we need to add a displacement */ 5262 gen_exts(ot, s->T1); 5263 tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot); 5264 tcg_gen_shli_tl(s->tmp0, s->tmp0, ot); 5265 tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0); 5266 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 5267 if (!(s->prefix & PREFIX_LOCK)) { 5268 gen_op_ld_v(s, ot, s->T0, s->A0); 5269 } 5270 } else { 5271 gen_op_mov_v_reg(s, ot, s->T0, rm); 5272 } 5273 bt_op: 5274 tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1); 5275 tcg_gen_movi_tl(s->tmp0, 1); 5276 tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1); 5277 if (s->prefix & PREFIX_LOCK) { 5278 switch (op) { 5279 case 0: /* bt */ 5280 /* Needs no atomic ops; we surpressed the normal 5281 memory load for LOCK above so do it now. */ 5282 gen_op_ld_v(s, ot, s->T0, s->A0); 5283 break; 5284 case 1: /* bts */ 5285 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0, 5286 s->mem_index, ot | MO_LE); 5287 break; 5288 case 2: /* btr */ 5289 tcg_gen_not_tl(s->tmp0, s->tmp0); 5290 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0, 5291 s->mem_index, ot | MO_LE); 5292 break; 5293 default: 5294 case 3: /* btc */ 5295 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0, 5296 s->mem_index, ot | MO_LE); 5297 break; 5298 } 5299 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 5300 } else { 5301 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 5302 switch (op) { 5303 case 0: /* bt */ 5304 /* Data already loaded; nothing to do. */ 5305 break; 5306 case 1: /* bts */ 5307 tcg_gen_or_tl(s->T0, s->T0, s->tmp0); 5308 break; 5309 case 2: /* btr */ 5310 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0); 5311 break; 5312 default: 5313 case 3: /* btc */ 5314 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0); 5315 break; 5316 } 5317 if (op != 0) { 5318 if (mod != 3) { 5319 gen_op_st_v(s, ot, s->T0, s->A0); 5320 } else { 5321 gen_op_mov_reg_v(s, ot, rm, s->T0); 5322 } 5323 } 5324 } 5325 5326 /* Delay all CC updates until after the store above. Note that 5327 C is the result of the test, Z is unchanged, and the others 5328 are all undefined. */ 5329 switch (s->cc_op) { 5330 case CC_OP_MULB ... CC_OP_MULQ: 5331 case CC_OP_ADDB ... CC_OP_ADDQ: 5332 case CC_OP_ADCB ... CC_OP_ADCQ: 5333 case CC_OP_SUBB ... CC_OP_SUBQ: 5334 case CC_OP_SBBB ... CC_OP_SBBQ: 5335 case CC_OP_LOGICB ... CC_OP_LOGICQ: 5336 case CC_OP_INCB ... CC_OP_INCQ: 5337 case CC_OP_DECB ... CC_OP_DECQ: 5338 case CC_OP_SHLB ... CC_OP_SHLQ: 5339 case CC_OP_SARB ... CC_OP_SARQ: 5340 case CC_OP_BMILGB ... CC_OP_BMILGQ: 5341 /* Z was going to be computed from the non-zero status of CC_DST. 5342 We can get that same Z value (and the new C value) by leaving 5343 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the 5344 same width. */ 5345 tcg_gen_mov_tl(cpu_cc_src, s->tmp4); 5346 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB); 5347 break; 5348 default: 5349 /* Otherwise, generate EFLAGS and replace the C bit. */ 5350 gen_compute_eflags(s); 5351 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4, 5352 ctz32(CC_C), 1); 5353 break; 5354 } 5355 break; 5356 case 0x1bc: /* bsf / tzcnt */ 5357 case 0x1bd: /* bsr / lzcnt */ 5358 ot = dflag; 5359 modrm = x86_ldub_code(env, s); 5360 reg = ((modrm >> 3) & 7) | REX_R(s); 5361 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 5362 gen_extu(ot, s->T0); 5363 5364 /* Note that lzcnt and tzcnt are in different extensions. */ 5365 if ((prefixes & PREFIX_REPZ) 5366 && (b & 1 5367 ? s->cpuid_ext3_features & CPUID_EXT3_ABM 5368 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) { 5369 int size = 8 << ot; 5370 /* For lzcnt/tzcnt, C bit is defined related to the input. */ 5371 tcg_gen_mov_tl(cpu_cc_src, s->T0); 5372 if (b & 1) { 5373 /* For lzcnt, reduce the target_ulong result by the 5374 number of zeros that we expect to find at the top. */ 5375 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS); 5376 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size); 5377 } else { 5378 /* For tzcnt, a zero input must return the operand size. */ 5379 tcg_gen_ctzi_tl(s->T0, s->T0, size); 5380 } 5381 /* For lzcnt/tzcnt, Z bit is defined related to the result. */ 5382 gen_op_update1_cc(s); 5383 set_cc_op(s, CC_OP_BMILGB + ot); 5384 } else { 5385 /* For bsr/bsf, only the Z bit is defined and it is related 5386 to the input and not the result. */ 5387 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 5388 set_cc_op(s, CC_OP_LOGICB + ot); 5389 5390 /* ??? The manual says that the output is undefined when the 5391 input is zero, but real hardware leaves it unchanged, and 5392 real programs appear to depend on that. Accomplish this 5393 by passing the output as the value to return upon zero. */ 5394 if (b & 1) { 5395 /* For bsr, return the bit index of the first 1 bit, 5396 not the count of leading zeros. */ 5397 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1); 5398 tcg_gen_clz_tl(s->T0, s->T0, s->T1); 5399 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1); 5400 } else { 5401 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]); 5402 } 5403 } 5404 gen_op_mov_reg_v(s, ot, reg, s->T0); 5405 break; 5406 /************************/ 5407 /* bcd */ 5408 case 0x27: /* daa */ 5409 if (CODE64(s)) 5410 goto illegal_op; 5411 gen_update_cc_op(s); 5412 gen_helper_daa(cpu_env); 5413 set_cc_op(s, CC_OP_EFLAGS); 5414 break; 5415 case 0x2f: /* das */ 5416 if (CODE64(s)) 5417 goto illegal_op; 5418 gen_update_cc_op(s); 5419 gen_helper_das(cpu_env); 5420 set_cc_op(s, CC_OP_EFLAGS); 5421 break; 5422 case 0x37: /* aaa */ 5423 if (CODE64(s)) 5424 goto illegal_op; 5425 gen_update_cc_op(s); 5426 gen_helper_aaa(cpu_env); 5427 set_cc_op(s, CC_OP_EFLAGS); 5428 break; 5429 case 0x3f: /* aas */ 5430 if (CODE64(s)) 5431 goto illegal_op; 5432 gen_update_cc_op(s); 5433 gen_helper_aas(cpu_env); 5434 set_cc_op(s, CC_OP_EFLAGS); 5435 break; 5436 case 0xd4: /* aam */ 5437 if (CODE64(s)) 5438 goto illegal_op; 5439 val = x86_ldub_code(env, s); 5440 if (val == 0) { 5441 gen_exception(s, EXCP00_DIVZ); 5442 } else { 5443 gen_helper_aam(cpu_env, tcg_const_i32(val)); 5444 set_cc_op(s, CC_OP_LOGICB); 5445 } 5446 break; 5447 case 0xd5: /* aad */ 5448 if (CODE64(s)) 5449 goto illegal_op; 5450 val = x86_ldub_code(env, s); 5451 gen_helper_aad(cpu_env, tcg_const_i32(val)); 5452 set_cc_op(s, CC_OP_LOGICB); 5453 break; 5454 /************************/ 5455 /* misc */ 5456 case 0x90: /* nop */ 5457 /* XXX: correct lock test for all insn */ 5458 if (prefixes & PREFIX_LOCK) { 5459 goto illegal_op; 5460 } 5461 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */ 5462 if (REX_B(s)) { 5463 goto do_xchg_reg_eax; 5464 } 5465 if (prefixes & PREFIX_REPZ) { 5466 gen_update_cc_op(s); 5467 gen_update_eip_cur(s); 5468 gen_helper_pause(cpu_env, cur_insn_len_i32(s)); 5469 s->base.is_jmp = DISAS_NORETURN; 5470 } 5471 break; 5472 case 0x9b: /* fwait */ 5473 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == 5474 (HF_MP_MASK | HF_TS_MASK)) { 5475 gen_exception(s, EXCP07_PREX); 5476 } else { 5477 gen_helper_fwait(cpu_env); 5478 } 5479 break; 5480 case 0xcc: /* int3 */ 5481 gen_interrupt(s, EXCP03_INT3); 5482 break; 5483 case 0xcd: /* int N */ 5484 val = x86_ldub_code(env, s); 5485 if (check_vm86_iopl(s)) { 5486 gen_interrupt(s, val); 5487 } 5488 break; 5489 case 0xce: /* into */ 5490 if (CODE64(s)) 5491 goto illegal_op; 5492 gen_update_cc_op(s); 5493 gen_update_eip_cur(s); 5494 gen_helper_into(cpu_env, cur_insn_len_i32(s)); 5495 break; 5496 #ifdef WANT_ICEBP 5497 case 0xf1: /* icebp (undocumented, exits to external debugger) */ 5498 gen_svm_check_intercept(s, SVM_EXIT_ICEBP); 5499 gen_debug(s); 5500 break; 5501 #endif 5502 case 0xfa: /* cli */ 5503 if (check_iopl(s)) { 5504 gen_helper_cli(cpu_env); 5505 } 5506 break; 5507 case 0xfb: /* sti */ 5508 if (check_iopl(s)) { 5509 gen_helper_sti(cpu_env); 5510 /* interruptions are enabled only the first insn after sti */ 5511 gen_update_eip_next(s); 5512 gen_eob_inhibit_irq(s, true); 5513 } 5514 break; 5515 case 0x62: /* bound */ 5516 if (CODE64(s)) 5517 goto illegal_op; 5518 ot = dflag; 5519 modrm = x86_ldub_code(env, s); 5520 reg = (modrm >> 3) & 7; 5521 mod = (modrm >> 6) & 3; 5522 if (mod == 3) 5523 goto illegal_op; 5524 gen_op_mov_v_reg(s, ot, s->T0, reg); 5525 gen_lea_modrm(env, s, modrm); 5526 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5527 if (ot == MO_16) { 5528 gen_helper_boundw(cpu_env, s->A0, s->tmp2_i32); 5529 } else { 5530 gen_helper_boundl(cpu_env, s->A0, s->tmp2_i32); 5531 } 5532 break; 5533 case 0x1c8 ... 0x1cf: /* bswap reg */ 5534 reg = (b & 7) | REX_B(s); 5535 #ifdef TARGET_X86_64 5536 if (dflag == MO_64) { 5537 tcg_gen_bswap64_i64(cpu_regs[reg], cpu_regs[reg]); 5538 break; 5539 } 5540 #endif 5541 tcg_gen_bswap32_tl(cpu_regs[reg], cpu_regs[reg], TCG_BSWAP_OZ); 5542 break; 5543 case 0xd6: /* salc */ 5544 if (CODE64(s)) 5545 goto illegal_op; 5546 gen_compute_eflags_c(s, s->T0); 5547 tcg_gen_neg_tl(s->T0, s->T0); 5548 gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0); 5549 break; 5550 case 0xe0: /* loopnz */ 5551 case 0xe1: /* loopz */ 5552 case 0xe2: /* loop */ 5553 case 0xe3: /* jecxz */ 5554 { 5555 TCGLabel *l1, *l2; 5556 int diff = (int8_t)insn_get(env, s, MO_8); 5557 5558 l1 = gen_new_label(); 5559 l2 = gen_new_label(); 5560 gen_update_cc_op(s); 5561 b &= 3; 5562 switch(b) { 5563 case 0: /* loopnz */ 5564 case 1: /* loopz */ 5565 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 5566 gen_op_jz_ecx(s, l2); 5567 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1); 5568 break; 5569 case 2: /* loop */ 5570 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 5571 gen_op_jnz_ecx(s, l1); 5572 break; 5573 default: 5574 case 3: /* jcxz */ 5575 gen_op_jz_ecx(s, l1); 5576 break; 5577 } 5578 5579 gen_set_label(l2); 5580 gen_jmp_rel_csize(s, 0, 1); 5581 5582 gen_set_label(l1); 5583 gen_jmp_rel(s, dflag, diff, 0); 5584 } 5585 break; 5586 case 0x130: /* wrmsr */ 5587 case 0x132: /* rdmsr */ 5588 if (check_cpl0(s)) { 5589 gen_update_cc_op(s); 5590 gen_update_eip_cur(s); 5591 if (b & 2) { 5592 gen_helper_rdmsr(cpu_env); 5593 } else { 5594 gen_helper_wrmsr(cpu_env); 5595 s->base.is_jmp = DISAS_EOB_NEXT; 5596 } 5597 } 5598 break; 5599 case 0x131: /* rdtsc */ 5600 gen_update_cc_op(s); 5601 gen_update_eip_cur(s); 5602 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 5603 gen_io_start(); 5604 s->base.is_jmp = DISAS_TOO_MANY; 5605 } 5606 gen_helper_rdtsc(cpu_env); 5607 break; 5608 case 0x133: /* rdpmc */ 5609 gen_update_cc_op(s); 5610 gen_update_eip_cur(s); 5611 gen_helper_rdpmc(cpu_env); 5612 s->base.is_jmp = DISAS_NORETURN; 5613 break; 5614 case 0x134: /* sysenter */ 5615 /* For Intel SYSENTER is valid on 64-bit */ 5616 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) 5617 goto illegal_op; 5618 if (!PE(s)) { 5619 gen_exception_gpf(s); 5620 } else { 5621 gen_helper_sysenter(cpu_env); 5622 s->base.is_jmp = DISAS_EOB_ONLY; 5623 } 5624 break; 5625 case 0x135: /* sysexit */ 5626 /* For Intel SYSEXIT is valid on 64-bit */ 5627 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) 5628 goto illegal_op; 5629 if (!PE(s)) { 5630 gen_exception_gpf(s); 5631 } else { 5632 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1)); 5633 s->base.is_jmp = DISAS_EOB_ONLY; 5634 } 5635 break; 5636 #ifdef TARGET_X86_64 5637 case 0x105: /* syscall */ 5638 /* XXX: is it usable in real mode ? */ 5639 gen_update_cc_op(s); 5640 gen_update_eip_cur(s); 5641 gen_helper_syscall(cpu_env, cur_insn_len_i32(s)); 5642 /* TF handling for the syscall insn is different. The TF bit is checked 5643 after the syscall insn completes. This allows #DB to not be 5644 generated after one has entered CPL0 if TF is set in FMASK. */ 5645 gen_eob_worker(s, false, true); 5646 break; 5647 case 0x107: /* sysret */ 5648 if (!PE(s)) { 5649 gen_exception_gpf(s); 5650 } else { 5651 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1)); 5652 /* condition codes are modified only in long mode */ 5653 if (LMA(s)) { 5654 set_cc_op(s, CC_OP_EFLAGS); 5655 } 5656 /* TF handling for the sysret insn is different. The TF bit is 5657 checked after the sysret insn completes. This allows #DB to be 5658 generated "as if" the syscall insn in userspace has just 5659 completed. */ 5660 gen_eob_worker(s, false, true); 5661 } 5662 break; 5663 #endif 5664 case 0x1a2: /* cpuid */ 5665 gen_update_cc_op(s); 5666 gen_update_eip_cur(s); 5667 gen_helper_cpuid(cpu_env); 5668 break; 5669 case 0xf4: /* hlt */ 5670 if (check_cpl0(s)) { 5671 gen_update_cc_op(s); 5672 gen_update_eip_cur(s); 5673 gen_helper_hlt(cpu_env, cur_insn_len_i32(s)); 5674 s->base.is_jmp = DISAS_NORETURN; 5675 } 5676 break; 5677 case 0x100: 5678 modrm = x86_ldub_code(env, s); 5679 mod = (modrm >> 6) & 3; 5680 op = (modrm >> 3) & 7; 5681 switch(op) { 5682 case 0: /* sldt */ 5683 if (!PE(s) || VM86(s)) 5684 goto illegal_op; 5685 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 5686 break; 5687 } 5688 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ); 5689 tcg_gen_ld32u_tl(s->T0, cpu_env, 5690 offsetof(CPUX86State, ldt.selector)); 5691 ot = mod == 3 ? dflag : MO_16; 5692 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 5693 break; 5694 case 2: /* lldt */ 5695 if (!PE(s) || VM86(s)) 5696 goto illegal_op; 5697 if (check_cpl0(s)) { 5698 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE); 5699 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 5700 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5701 gen_helper_lldt(cpu_env, s->tmp2_i32); 5702 } 5703 break; 5704 case 1: /* str */ 5705 if (!PE(s) || VM86(s)) 5706 goto illegal_op; 5707 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 5708 break; 5709 } 5710 gen_svm_check_intercept(s, SVM_EXIT_TR_READ); 5711 tcg_gen_ld32u_tl(s->T0, cpu_env, 5712 offsetof(CPUX86State, tr.selector)); 5713 ot = mod == 3 ? dflag : MO_16; 5714 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 5715 break; 5716 case 3: /* ltr */ 5717 if (!PE(s) || VM86(s)) 5718 goto illegal_op; 5719 if (check_cpl0(s)) { 5720 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE); 5721 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 5722 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5723 gen_helper_ltr(cpu_env, s->tmp2_i32); 5724 } 5725 break; 5726 case 4: /* verr */ 5727 case 5: /* verw */ 5728 if (!PE(s) || VM86(s)) 5729 goto illegal_op; 5730 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 5731 gen_update_cc_op(s); 5732 if (op == 4) { 5733 gen_helper_verr(cpu_env, s->T0); 5734 } else { 5735 gen_helper_verw(cpu_env, s->T0); 5736 } 5737 set_cc_op(s, CC_OP_EFLAGS); 5738 break; 5739 default: 5740 goto unknown_op; 5741 } 5742 break; 5743 5744 case 0x101: 5745 modrm = x86_ldub_code(env, s); 5746 switch (modrm) { 5747 CASE_MODRM_MEM_OP(0): /* sgdt */ 5748 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 5749 break; 5750 } 5751 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ); 5752 gen_lea_modrm(env, s, modrm); 5753 tcg_gen_ld32u_tl(s->T0, 5754 cpu_env, offsetof(CPUX86State, gdt.limit)); 5755 gen_op_st_v(s, MO_16, s->T0, s->A0); 5756 gen_add_A0_im(s, 2); 5757 tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base)); 5758 if (dflag == MO_16) { 5759 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 5760 } 5761 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 5762 break; 5763 5764 case 0xc8: /* monitor */ 5765 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 5766 goto illegal_op; 5767 } 5768 gen_update_cc_op(s); 5769 gen_update_eip_cur(s); 5770 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 5771 gen_extu(s->aflag, s->A0); 5772 gen_add_A0_ds_seg(s); 5773 gen_helper_monitor(cpu_env, s->A0); 5774 break; 5775 5776 case 0xc9: /* mwait */ 5777 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 5778 goto illegal_op; 5779 } 5780 gen_update_cc_op(s); 5781 gen_update_eip_cur(s); 5782 gen_helper_mwait(cpu_env, cur_insn_len_i32(s)); 5783 s->base.is_jmp = DISAS_NORETURN; 5784 break; 5785 5786 case 0xca: /* clac */ 5787 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 5788 || CPL(s) != 0) { 5789 goto illegal_op; 5790 } 5791 gen_helper_clac(cpu_env); 5792 s->base.is_jmp = DISAS_EOB_NEXT; 5793 break; 5794 5795 case 0xcb: /* stac */ 5796 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 5797 || CPL(s) != 0) { 5798 goto illegal_op; 5799 } 5800 gen_helper_stac(cpu_env); 5801 s->base.is_jmp = DISAS_EOB_NEXT; 5802 break; 5803 5804 CASE_MODRM_MEM_OP(1): /* sidt */ 5805 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 5806 break; 5807 } 5808 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ); 5809 gen_lea_modrm(env, s, modrm); 5810 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit)); 5811 gen_op_st_v(s, MO_16, s->T0, s->A0); 5812 gen_add_A0_im(s, 2); 5813 tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base)); 5814 if (dflag == MO_16) { 5815 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 5816 } 5817 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 5818 break; 5819 5820 case 0xd0: /* xgetbv */ 5821 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 5822 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 5823 | PREFIX_REPZ | PREFIX_REPNZ))) { 5824 goto illegal_op; 5825 } 5826 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 5827 gen_helper_xgetbv(s->tmp1_i64, cpu_env, s->tmp2_i32); 5828 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 5829 break; 5830 5831 case 0xd1: /* xsetbv */ 5832 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 5833 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 5834 | PREFIX_REPZ | PREFIX_REPNZ))) { 5835 goto illegal_op; 5836 } 5837 if (!check_cpl0(s)) { 5838 break; 5839 } 5840 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 5841 cpu_regs[R_EDX]); 5842 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 5843 gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64); 5844 /* End TB because translation flags may change. */ 5845 s->base.is_jmp = DISAS_EOB_NEXT; 5846 break; 5847 5848 case 0xd8: /* VMRUN */ 5849 if (!SVME(s) || !PE(s)) { 5850 goto illegal_op; 5851 } 5852 if (!check_cpl0(s)) { 5853 break; 5854 } 5855 gen_update_cc_op(s); 5856 gen_update_eip_cur(s); 5857 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1), 5858 cur_insn_len_i32(s)); 5859 tcg_gen_exit_tb(NULL, 0); 5860 s->base.is_jmp = DISAS_NORETURN; 5861 break; 5862 5863 case 0xd9: /* VMMCALL */ 5864 if (!SVME(s)) { 5865 goto illegal_op; 5866 } 5867 gen_update_cc_op(s); 5868 gen_update_eip_cur(s); 5869 gen_helper_vmmcall(cpu_env); 5870 break; 5871 5872 case 0xda: /* VMLOAD */ 5873 if (!SVME(s) || !PE(s)) { 5874 goto illegal_op; 5875 } 5876 if (!check_cpl0(s)) { 5877 break; 5878 } 5879 gen_update_cc_op(s); 5880 gen_update_eip_cur(s); 5881 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1)); 5882 break; 5883 5884 case 0xdb: /* VMSAVE */ 5885 if (!SVME(s) || !PE(s)) { 5886 goto illegal_op; 5887 } 5888 if (!check_cpl0(s)) { 5889 break; 5890 } 5891 gen_update_cc_op(s); 5892 gen_update_eip_cur(s); 5893 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1)); 5894 break; 5895 5896 case 0xdc: /* STGI */ 5897 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 5898 || !PE(s)) { 5899 goto illegal_op; 5900 } 5901 if (!check_cpl0(s)) { 5902 break; 5903 } 5904 gen_update_cc_op(s); 5905 gen_helper_stgi(cpu_env); 5906 s->base.is_jmp = DISAS_EOB_NEXT; 5907 break; 5908 5909 case 0xdd: /* CLGI */ 5910 if (!SVME(s) || !PE(s)) { 5911 goto illegal_op; 5912 } 5913 if (!check_cpl0(s)) { 5914 break; 5915 } 5916 gen_update_cc_op(s); 5917 gen_update_eip_cur(s); 5918 gen_helper_clgi(cpu_env); 5919 break; 5920 5921 case 0xde: /* SKINIT */ 5922 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 5923 || !PE(s)) { 5924 goto illegal_op; 5925 } 5926 gen_svm_check_intercept(s, SVM_EXIT_SKINIT); 5927 /* If not intercepted, not implemented -- raise #UD. */ 5928 goto illegal_op; 5929 5930 case 0xdf: /* INVLPGA */ 5931 if (!SVME(s) || !PE(s)) { 5932 goto illegal_op; 5933 } 5934 if (!check_cpl0(s)) { 5935 break; 5936 } 5937 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA); 5938 if (s->aflag == MO_64) { 5939 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 5940 } else { 5941 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]); 5942 } 5943 gen_helper_flush_page(cpu_env, s->A0); 5944 s->base.is_jmp = DISAS_EOB_NEXT; 5945 break; 5946 5947 CASE_MODRM_MEM_OP(2): /* lgdt */ 5948 if (!check_cpl0(s)) { 5949 break; 5950 } 5951 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE); 5952 gen_lea_modrm(env, s, modrm); 5953 gen_op_ld_v(s, MO_16, s->T1, s->A0); 5954 gen_add_A0_im(s, 2); 5955 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 5956 if (dflag == MO_16) { 5957 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 5958 } 5959 tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base)); 5960 tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, gdt.limit)); 5961 break; 5962 5963 CASE_MODRM_MEM_OP(3): /* lidt */ 5964 if (!check_cpl0(s)) { 5965 break; 5966 } 5967 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE); 5968 gen_lea_modrm(env, s, modrm); 5969 gen_op_ld_v(s, MO_16, s->T1, s->A0); 5970 gen_add_A0_im(s, 2); 5971 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 5972 if (dflag == MO_16) { 5973 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 5974 } 5975 tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base)); 5976 tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, idt.limit)); 5977 break; 5978 5979 CASE_MODRM_OP(4): /* smsw */ 5980 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 5981 break; 5982 } 5983 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0); 5984 tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0])); 5985 /* 5986 * In 32-bit mode, the higher 16 bits of the destination 5987 * register are undefined. In practice CR0[31:0] is stored 5988 * just like in 64-bit mode. 5989 */ 5990 mod = (modrm >> 6) & 3; 5991 ot = (mod != 3 ? MO_16 : s->dflag); 5992 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 5993 break; 5994 case 0xee: /* rdpkru */ 5995 if (prefixes & PREFIX_LOCK) { 5996 goto illegal_op; 5997 } 5998 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 5999 gen_helper_rdpkru(s->tmp1_i64, cpu_env, s->tmp2_i32); 6000 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 6001 break; 6002 case 0xef: /* wrpkru */ 6003 if (prefixes & PREFIX_LOCK) { 6004 goto illegal_op; 6005 } 6006 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 6007 cpu_regs[R_EDX]); 6008 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 6009 gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64); 6010 break; 6011 6012 CASE_MODRM_OP(6): /* lmsw */ 6013 if (!check_cpl0(s)) { 6014 break; 6015 } 6016 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 6017 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 6018 /* 6019 * Only the 4 lower bits of CR0 are modified. 6020 * PE cannot be set to zero if already set to one. 6021 */ 6022 tcg_gen_ld_tl(s->T1, cpu_env, offsetof(CPUX86State, cr[0])); 6023 tcg_gen_andi_tl(s->T0, s->T0, 0xf); 6024 tcg_gen_andi_tl(s->T1, s->T1, ~0xe); 6025 tcg_gen_or_tl(s->T0, s->T0, s->T1); 6026 gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0); 6027 s->base.is_jmp = DISAS_EOB_NEXT; 6028 break; 6029 6030 CASE_MODRM_MEM_OP(7): /* invlpg */ 6031 if (!check_cpl0(s)) { 6032 break; 6033 } 6034 gen_svm_check_intercept(s, SVM_EXIT_INVLPG); 6035 gen_lea_modrm(env, s, modrm); 6036 gen_helper_flush_page(cpu_env, s->A0); 6037 s->base.is_jmp = DISAS_EOB_NEXT; 6038 break; 6039 6040 case 0xf8: /* swapgs */ 6041 #ifdef TARGET_X86_64 6042 if (CODE64(s)) { 6043 if (check_cpl0(s)) { 6044 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]); 6045 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env, 6046 offsetof(CPUX86State, kernelgsbase)); 6047 tcg_gen_st_tl(s->T0, cpu_env, 6048 offsetof(CPUX86State, kernelgsbase)); 6049 } 6050 break; 6051 } 6052 #endif 6053 goto illegal_op; 6054 6055 case 0xf9: /* rdtscp */ 6056 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) { 6057 goto illegal_op; 6058 } 6059 gen_update_cc_op(s); 6060 gen_update_eip_cur(s); 6061 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6062 gen_io_start(); 6063 s->base.is_jmp = DISAS_TOO_MANY; 6064 } 6065 gen_helper_rdtscp(cpu_env); 6066 break; 6067 6068 default: 6069 goto unknown_op; 6070 } 6071 break; 6072 6073 case 0x108: /* invd */ 6074 case 0x109: /* wbinvd */ 6075 if (check_cpl0(s)) { 6076 gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD); 6077 /* nothing to do */ 6078 } 6079 break; 6080 case 0x63: /* arpl or movslS (x86_64) */ 6081 #ifdef TARGET_X86_64 6082 if (CODE64(s)) { 6083 int d_ot; 6084 /* d_ot is the size of destination */ 6085 d_ot = dflag; 6086 6087 modrm = x86_ldub_code(env, s); 6088 reg = ((modrm >> 3) & 7) | REX_R(s); 6089 mod = (modrm >> 6) & 3; 6090 rm = (modrm & 7) | REX_B(s); 6091 6092 if (mod == 3) { 6093 gen_op_mov_v_reg(s, MO_32, s->T0, rm); 6094 /* sign extend */ 6095 if (d_ot == MO_64) { 6096 tcg_gen_ext32s_tl(s->T0, s->T0); 6097 } 6098 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 6099 } else { 6100 gen_lea_modrm(env, s, modrm); 6101 gen_op_ld_v(s, MO_32 | MO_SIGN, s->T0, s->A0); 6102 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 6103 } 6104 } else 6105 #endif 6106 { 6107 TCGLabel *label1; 6108 TCGv t0, t1, t2, a0; 6109 6110 if (!PE(s) || VM86(s)) 6111 goto illegal_op; 6112 t0 = tcg_temp_local_new(); 6113 t1 = tcg_temp_local_new(); 6114 t2 = tcg_temp_local_new(); 6115 ot = MO_16; 6116 modrm = x86_ldub_code(env, s); 6117 reg = (modrm >> 3) & 7; 6118 mod = (modrm >> 6) & 3; 6119 rm = modrm & 7; 6120 if (mod != 3) { 6121 gen_lea_modrm(env, s, modrm); 6122 gen_op_ld_v(s, ot, t0, s->A0); 6123 a0 = tcg_temp_local_new(); 6124 tcg_gen_mov_tl(a0, s->A0); 6125 } else { 6126 gen_op_mov_v_reg(s, ot, t0, rm); 6127 a0 = NULL; 6128 } 6129 gen_op_mov_v_reg(s, ot, t1, reg); 6130 tcg_gen_andi_tl(s->tmp0, t0, 3); 6131 tcg_gen_andi_tl(t1, t1, 3); 6132 tcg_gen_movi_tl(t2, 0); 6133 label1 = gen_new_label(); 6134 tcg_gen_brcond_tl(TCG_COND_GE, s->tmp0, t1, label1); 6135 tcg_gen_andi_tl(t0, t0, ~3); 6136 tcg_gen_or_tl(t0, t0, t1); 6137 tcg_gen_movi_tl(t2, CC_Z); 6138 gen_set_label(label1); 6139 if (mod != 3) { 6140 gen_op_st_v(s, ot, t0, a0); 6141 tcg_temp_free(a0); 6142 } else { 6143 gen_op_mov_reg_v(s, ot, rm, t0); 6144 } 6145 gen_compute_eflags(s); 6146 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z); 6147 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2); 6148 tcg_temp_free(t0); 6149 tcg_temp_free(t1); 6150 tcg_temp_free(t2); 6151 } 6152 break; 6153 case 0x102: /* lar */ 6154 case 0x103: /* lsl */ 6155 { 6156 TCGLabel *label1; 6157 TCGv t0; 6158 if (!PE(s) || VM86(s)) 6159 goto illegal_op; 6160 ot = dflag != MO_16 ? MO_32 : MO_16; 6161 modrm = x86_ldub_code(env, s); 6162 reg = ((modrm >> 3) & 7) | REX_R(s); 6163 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 6164 t0 = tcg_temp_local_new(); 6165 gen_update_cc_op(s); 6166 if (b == 0x102) { 6167 gen_helper_lar(t0, cpu_env, s->T0); 6168 } else { 6169 gen_helper_lsl(t0, cpu_env, s->T0); 6170 } 6171 tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z); 6172 label1 = gen_new_label(); 6173 tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1); 6174 gen_op_mov_reg_v(s, ot, reg, t0); 6175 gen_set_label(label1); 6176 set_cc_op(s, CC_OP_EFLAGS); 6177 tcg_temp_free(t0); 6178 } 6179 break; 6180 case 0x118: 6181 modrm = x86_ldub_code(env, s); 6182 mod = (modrm >> 6) & 3; 6183 op = (modrm >> 3) & 7; 6184 switch(op) { 6185 case 0: /* prefetchnta */ 6186 case 1: /* prefetchnt0 */ 6187 case 2: /* prefetchnt0 */ 6188 case 3: /* prefetchnt0 */ 6189 if (mod == 3) 6190 goto illegal_op; 6191 gen_nop_modrm(env, s, modrm); 6192 /* nothing more to do */ 6193 break; 6194 default: /* nop (multi byte) */ 6195 gen_nop_modrm(env, s, modrm); 6196 break; 6197 } 6198 break; 6199 case 0x11a: 6200 modrm = x86_ldub_code(env, s); 6201 if (s->flags & HF_MPX_EN_MASK) { 6202 mod = (modrm >> 6) & 3; 6203 reg = ((modrm >> 3) & 7) | REX_R(s); 6204 if (prefixes & PREFIX_REPZ) { 6205 /* bndcl */ 6206 if (reg >= 4 6207 || (prefixes & PREFIX_LOCK) 6208 || s->aflag == MO_16) { 6209 goto illegal_op; 6210 } 6211 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]); 6212 } else if (prefixes & PREFIX_REPNZ) { 6213 /* bndcu */ 6214 if (reg >= 4 6215 || (prefixes & PREFIX_LOCK) 6216 || s->aflag == MO_16) { 6217 goto illegal_op; 6218 } 6219 TCGv_i64 notu = tcg_temp_new_i64(); 6220 tcg_gen_not_i64(notu, cpu_bndu[reg]); 6221 gen_bndck(env, s, modrm, TCG_COND_GTU, notu); 6222 tcg_temp_free_i64(notu); 6223 } else if (prefixes & PREFIX_DATA) { 6224 /* bndmov -- from reg/mem */ 6225 if (reg >= 4 || s->aflag == MO_16) { 6226 goto illegal_op; 6227 } 6228 if (mod == 3) { 6229 int reg2 = (modrm & 7) | REX_B(s); 6230 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 6231 goto illegal_op; 6232 } 6233 if (s->flags & HF_MPX_IU_MASK) { 6234 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]); 6235 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]); 6236 } 6237 } else { 6238 gen_lea_modrm(env, s, modrm); 6239 if (CODE64(s)) { 6240 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 6241 s->mem_index, MO_LEUQ); 6242 tcg_gen_addi_tl(s->A0, s->A0, 8); 6243 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 6244 s->mem_index, MO_LEUQ); 6245 } else { 6246 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 6247 s->mem_index, MO_LEUL); 6248 tcg_gen_addi_tl(s->A0, s->A0, 4); 6249 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 6250 s->mem_index, MO_LEUL); 6251 } 6252 /* bnd registers are now in-use */ 6253 gen_set_hflag(s, HF_MPX_IU_MASK); 6254 } 6255 } else if (mod != 3) { 6256 /* bndldx */ 6257 AddressParts a = gen_lea_modrm_0(env, s, modrm); 6258 if (reg >= 4 6259 || (prefixes & PREFIX_LOCK) 6260 || s->aflag == MO_16 6261 || a.base < -1) { 6262 goto illegal_op; 6263 } 6264 if (a.base >= 0) { 6265 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 6266 } else { 6267 tcg_gen_movi_tl(s->A0, 0); 6268 } 6269 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 6270 if (a.index >= 0) { 6271 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 6272 } else { 6273 tcg_gen_movi_tl(s->T0, 0); 6274 } 6275 if (CODE64(s)) { 6276 gen_helper_bndldx64(cpu_bndl[reg], cpu_env, s->A0, s->T0); 6277 tcg_gen_ld_i64(cpu_bndu[reg], cpu_env, 6278 offsetof(CPUX86State, mmx_t0.MMX_Q(0))); 6279 } else { 6280 gen_helper_bndldx32(cpu_bndu[reg], cpu_env, s->A0, s->T0); 6281 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]); 6282 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32); 6283 } 6284 gen_set_hflag(s, HF_MPX_IU_MASK); 6285 } 6286 } 6287 gen_nop_modrm(env, s, modrm); 6288 break; 6289 case 0x11b: 6290 modrm = x86_ldub_code(env, s); 6291 if (s->flags & HF_MPX_EN_MASK) { 6292 mod = (modrm >> 6) & 3; 6293 reg = ((modrm >> 3) & 7) | REX_R(s); 6294 if (mod != 3 && (prefixes & PREFIX_REPZ)) { 6295 /* bndmk */ 6296 if (reg >= 4 6297 || (prefixes & PREFIX_LOCK) 6298 || s->aflag == MO_16) { 6299 goto illegal_op; 6300 } 6301 AddressParts a = gen_lea_modrm_0(env, s, modrm); 6302 if (a.base >= 0) { 6303 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]); 6304 if (!CODE64(s)) { 6305 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]); 6306 } 6307 } else if (a.base == -1) { 6308 /* no base register has lower bound of 0 */ 6309 tcg_gen_movi_i64(cpu_bndl[reg], 0); 6310 } else { 6311 /* rip-relative generates #ud */ 6312 goto illegal_op; 6313 } 6314 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false)); 6315 if (!CODE64(s)) { 6316 tcg_gen_ext32u_tl(s->A0, s->A0); 6317 } 6318 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0); 6319 /* bnd registers are now in-use */ 6320 gen_set_hflag(s, HF_MPX_IU_MASK); 6321 break; 6322 } else if (prefixes & PREFIX_REPNZ) { 6323 /* bndcn */ 6324 if (reg >= 4 6325 || (prefixes & PREFIX_LOCK) 6326 || s->aflag == MO_16) { 6327 goto illegal_op; 6328 } 6329 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]); 6330 } else if (prefixes & PREFIX_DATA) { 6331 /* bndmov -- to reg/mem */ 6332 if (reg >= 4 || s->aflag == MO_16) { 6333 goto illegal_op; 6334 } 6335 if (mod == 3) { 6336 int reg2 = (modrm & 7) | REX_B(s); 6337 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 6338 goto illegal_op; 6339 } 6340 if (s->flags & HF_MPX_IU_MASK) { 6341 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]); 6342 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]); 6343 } 6344 } else { 6345 gen_lea_modrm(env, s, modrm); 6346 if (CODE64(s)) { 6347 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 6348 s->mem_index, MO_LEUQ); 6349 tcg_gen_addi_tl(s->A0, s->A0, 8); 6350 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 6351 s->mem_index, MO_LEUQ); 6352 } else { 6353 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 6354 s->mem_index, MO_LEUL); 6355 tcg_gen_addi_tl(s->A0, s->A0, 4); 6356 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 6357 s->mem_index, MO_LEUL); 6358 } 6359 } 6360 } else if (mod != 3) { 6361 /* bndstx */ 6362 AddressParts a = gen_lea_modrm_0(env, s, modrm); 6363 if (reg >= 4 6364 || (prefixes & PREFIX_LOCK) 6365 || s->aflag == MO_16 6366 || a.base < -1) { 6367 goto illegal_op; 6368 } 6369 if (a.base >= 0) { 6370 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 6371 } else { 6372 tcg_gen_movi_tl(s->A0, 0); 6373 } 6374 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 6375 if (a.index >= 0) { 6376 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 6377 } else { 6378 tcg_gen_movi_tl(s->T0, 0); 6379 } 6380 if (CODE64(s)) { 6381 gen_helper_bndstx64(cpu_env, s->A0, s->T0, 6382 cpu_bndl[reg], cpu_bndu[reg]); 6383 } else { 6384 gen_helper_bndstx32(cpu_env, s->A0, s->T0, 6385 cpu_bndl[reg], cpu_bndu[reg]); 6386 } 6387 } 6388 } 6389 gen_nop_modrm(env, s, modrm); 6390 break; 6391 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */ 6392 modrm = x86_ldub_code(env, s); 6393 gen_nop_modrm(env, s, modrm); 6394 break; 6395 6396 case 0x120: /* mov reg, crN */ 6397 case 0x122: /* mov crN, reg */ 6398 if (!check_cpl0(s)) { 6399 break; 6400 } 6401 modrm = x86_ldub_code(env, s); 6402 /* 6403 * Ignore the mod bits (assume (modrm&0xc0)==0xc0). 6404 * AMD documentation (24594.pdf) and testing of Intel 386 and 486 6405 * processors all show that the mod bits are assumed to be 1's, 6406 * regardless of actual values. 6407 */ 6408 rm = (modrm & 7) | REX_B(s); 6409 reg = ((modrm >> 3) & 7) | REX_R(s); 6410 switch (reg) { 6411 case 0: 6412 if ((prefixes & PREFIX_LOCK) && 6413 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) { 6414 reg = 8; 6415 } 6416 break; 6417 case 2: 6418 case 3: 6419 case 4: 6420 case 8: 6421 break; 6422 default: 6423 goto unknown_op; 6424 } 6425 ot = (CODE64(s) ? MO_64 : MO_32); 6426 6427 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6428 gen_io_start(); 6429 s->base.is_jmp = DISAS_TOO_MANY; 6430 } 6431 if (b & 2) { 6432 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg); 6433 gen_op_mov_v_reg(s, ot, s->T0, rm); 6434 gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0); 6435 s->base.is_jmp = DISAS_EOB_NEXT; 6436 } else { 6437 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg); 6438 gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg)); 6439 gen_op_mov_reg_v(s, ot, rm, s->T0); 6440 } 6441 break; 6442 6443 case 0x121: /* mov reg, drN */ 6444 case 0x123: /* mov drN, reg */ 6445 if (check_cpl0(s)) { 6446 modrm = x86_ldub_code(env, s); 6447 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). 6448 * AMD documentation (24594.pdf) and testing of 6449 * intel 386 and 486 processors all show that the mod bits 6450 * are assumed to be 1's, regardless of actual values. 6451 */ 6452 rm = (modrm & 7) | REX_B(s); 6453 reg = ((modrm >> 3) & 7) | REX_R(s); 6454 if (CODE64(s)) 6455 ot = MO_64; 6456 else 6457 ot = MO_32; 6458 if (reg >= 8) { 6459 goto illegal_op; 6460 } 6461 if (b & 2) { 6462 gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg); 6463 gen_op_mov_v_reg(s, ot, s->T0, rm); 6464 tcg_gen_movi_i32(s->tmp2_i32, reg); 6465 gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0); 6466 s->base.is_jmp = DISAS_EOB_NEXT; 6467 } else { 6468 gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg); 6469 tcg_gen_movi_i32(s->tmp2_i32, reg); 6470 gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32); 6471 gen_op_mov_reg_v(s, ot, rm, s->T0); 6472 } 6473 } 6474 break; 6475 case 0x106: /* clts */ 6476 if (check_cpl0(s)) { 6477 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 6478 gen_helper_clts(cpu_env); 6479 /* abort block because static cpu state changed */ 6480 s->base.is_jmp = DISAS_EOB_NEXT; 6481 } 6482 break; 6483 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */ 6484 case 0x1c3: /* MOVNTI reg, mem */ 6485 if (!(s->cpuid_features & CPUID_SSE2)) 6486 goto illegal_op; 6487 ot = mo_64_32(dflag); 6488 modrm = x86_ldub_code(env, s); 6489 mod = (modrm >> 6) & 3; 6490 if (mod == 3) 6491 goto illegal_op; 6492 reg = ((modrm >> 3) & 7) | REX_R(s); 6493 /* generate a generic store */ 6494 gen_ldst_modrm(env, s, modrm, ot, reg, 1); 6495 break; 6496 case 0x1ae: 6497 modrm = x86_ldub_code(env, s); 6498 switch (modrm) { 6499 CASE_MODRM_MEM_OP(0): /* fxsave */ 6500 if (!(s->cpuid_features & CPUID_FXSR) 6501 || (prefixes & PREFIX_LOCK)) { 6502 goto illegal_op; 6503 } 6504 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 6505 gen_exception(s, EXCP07_PREX); 6506 break; 6507 } 6508 gen_lea_modrm(env, s, modrm); 6509 gen_helper_fxsave(cpu_env, s->A0); 6510 break; 6511 6512 CASE_MODRM_MEM_OP(1): /* fxrstor */ 6513 if (!(s->cpuid_features & CPUID_FXSR) 6514 || (prefixes & PREFIX_LOCK)) { 6515 goto illegal_op; 6516 } 6517 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 6518 gen_exception(s, EXCP07_PREX); 6519 break; 6520 } 6521 gen_lea_modrm(env, s, modrm); 6522 gen_helper_fxrstor(cpu_env, s->A0); 6523 break; 6524 6525 CASE_MODRM_MEM_OP(2): /* ldmxcsr */ 6526 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 6527 goto illegal_op; 6528 } 6529 if (s->flags & HF_TS_MASK) { 6530 gen_exception(s, EXCP07_PREX); 6531 break; 6532 } 6533 gen_lea_modrm(env, s, modrm); 6534 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL); 6535 gen_helper_ldmxcsr(cpu_env, s->tmp2_i32); 6536 break; 6537 6538 CASE_MODRM_MEM_OP(3): /* stmxcsr */ 6539 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 6540 goto illegal_op; 6541 } 6542 if (s->flags & HF_TS_MASK) { 6543 gen_exception(s, EXCP07_PREX); 6544 break; 6545 } 6546 gen_helper_update_mxcsr(cpu_env); 6547 gen_lea_modrm(env, s, modrm); 6548 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, mxcsr)); 6549 gen_op_st_v(s, MO_32, s->T0, s->A0); 6550 break; 6551 6552 CASE_MODRM_MEM_OP(4): /* xsave */ 6553 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 6554 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 6555 | PREFIX_REPZ | PREFIX_REPNZ))) { 6556 goto illegal_op; 6557 } 6558 gen_lea_modrm(env, s, modrm); 6559 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 6560 cpu_regs[R_EDX]); 6561 gen_helper_xsave(cpu_env, s->A0, s->tmp1_i64); 6562 break; 6563 6564 CASE_MODRM_MEM_OP(5): /* xrstor */ 6565 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 6566 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 6567 | PREFIX_REPZ | PREFIX_REPNZ))) { 6568 goto illegal_op; 6569 } 6570 gen_lea_modrm(env, s, modrm); 6571 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 6572 cpu_regs[R_EDX]); 6573 gen_helper_xrstor(cpu_env, s->A0, s->tmp1_i64); 6574 /* XRSTOR is how MPX is enabled, which changes how 6575 we translate. Thus we need to end the TB. */ 6576 s->base.is_jmp = DISAS_EOB_NEXT; 6577 break; 6578 6579 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */ 6580 if (prefixes & PREFIX_LOCK) { 6581 goto illegal_op; 6582 } 6583 if (prefixes & PREFIX_DATA) { 6584 /* clwb */ 6585 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) { 6586 goto illegal_op; 6587 } 6588 gen_nop_modrm(env, s, modrm); 6589 } else { 6590 /* xsaveopt */ 6591 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 6592 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0 6593 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) { 6594 goto illegal_op; 6595 } 6596 gen_lea_modrm(env, s, modrm); 6597 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 6598 cpu_regs[R_EDX]); 6599 gen_helper_xsaveopt(cpu_env, s->A0, s->tmp1_i64); 6600 } 6601 break; 6602 6603 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */ 6604 if (prefixes & PREFIX_LOCK) { 6605 goto illegal_op; 6606 } 6607 if (prefixes & PREFIX_DATA) { 6608 /* clflushopt */ 6609 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) { 6610 goto illegal_op; 6611 } 6612 } else { 6613 /* clflush */ 6614 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) 6615 || !(s->cpuid_features & CPUID_CLFLUSH)) { 6616 goto illegal_op; 6617 } 6618 } 6619 gen_nop_modrm(env, s, modrm); 6620 break; 6621 6622 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */ 6623 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */ 6624 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */ 6625 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */ 6626 if (CODE64(s) 6627 && (prefixes & PREFIX_REPZ) 6628 && !(prefixes & PREFIX_LOCK) 6629 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) { 6630 TCGv base, treg, src, dst; 6631 6632 /* Preserve hflags bits by testing CR4 at runtime. */ 6633 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK); 6634 gen_helper_cr4_testbit(cpu_env, s->tmp2_i32); 6635 6636 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS]; 6637 treg = cpu_regs[(modrm & 7) | REX_B(s)]; 6638 6639 if (modrm & 0x10) { 6640 /* wr*base */ 6641 dst = base, src = treg; 6642 } else { 6643 /* rd*base */ 6644 dst = treg, src = base; 6645 } 6646 6647 if (s->dflag == MO_32) { 6648 tcg_gen_ext32u_tl(dst, src); 6649 } else { 6650 tcg_gen_mov_tl(dst, src); 6651 } 6652 break; 6653 } 6654 goto unknown_op; 6655 6656 case 0xf8: /* sfence / pcommit */ 6657 if (prefixes & PREFIX_DATA) { 6658 /* pcommit */ 6659 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT) 6660 || (prefixes & PREFIX_LOCK)) { 6661 goto illegal_op; 6662 } 6663 break; 6664 } 6665 /* fallthru */ 6666 case 0xf9 ... 0xff: /* sfence */ 6667 if (!(s->cpuid_features & CPUID_SSE) 6668 || (prefixes & PREFIX_LOCK)) { 6669 goto illegal_op; 6670 } 6671 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC); 6672 break; 6673 case 0xe8 ... 0xef: /* lfence */ 6674 if (!(s->cpuid_features & CPUID_SSE) 6675 || (prefixes & PREFIX_LOCK)) { 6676 goto illegal_op; 6677 } 6678 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC); 6679 break; 6680 case 0xf0 ... 0xf7: /* mfence */ 6681 if (!(s->cpuid_features & CPUID_SSE2) 6682 || (prefixes & PREFIX_LOCK)) { 6683 goto illegal_op; 6684 } 6685 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 6686 break; 6687 6688 default: 6689 goto unknown_op; 6690 } 6691 break; 6692 6693 case 0x10d: /* 3DNow! prefetch(w) */ 6694 modrm = x86_ldub_code(env, s); 6695 mod = (modrm >> 6) & 3; 6696 if (mod == 3) 6697 goto illegal_op; 6698 gen_nop_modrm(env, s, modrm); 6699 break; 6700 case 0x1aa: /* rsm */ 6701 gen_svm_check_intercept(s, SVM_EXIT_RSM); 6702 if (!(s->flags & HF_SMM_MASK)) 6703 goto illegal_op; 6704 #ifdef CONFIG_USER_ONLY 6705 /* we should not be in SMM mode */ 6706 g_assert_not_reached(); 6707 #else 6708 gen_update_cc_op(s); 6709 gen_update_eip_next(s); 6710 gen_helper_rsm(cpu_env); 6711 #endif /* CONFIG_USER_ONLY */ 6712 s->base.is_jmp = DISAS_EOB_ONLY; 6713 break; 6714 case 0x1b8: /* SSE4.2 popcnt */ 6715 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) != 6716 PREFIX_REPZ) 6717 goto illegal_op; 6718 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT)) 6719 goto illegal_op; 6720 6721 modrm = x86_ldub_code(env, s); 6722 reg = ((modrm >> 3) & 7) | REX_R(s); 6723 6724 if (s->prefix & PREFIX_DATA) { 6725 ot = MO_16; 6726 } else { 6727 ot = mo_64_32(dflag); 6728 } 6729 6730 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 6731 gen_extu(ot, s->T0); 6732 tcg_gen_mov_tl(cpu_cc_src, s->T0); 6733 tcg_gen_ctpop_tl(s->T0, s->T0); 6734 gen_op_mov_reg_v(s, ot, reg, s->T0); 6735 6736 set_cc_op(s, CC_OP_POPCNT); 6737 break; 6738 case 0x10e ... 0x117: 6739 case 0x128 ... 0x12f: 6740 case 0x138 ... 0x13a: 6741 case 0x150 ... 0x179: 6742 case 0x17c ... 0x17f: 6743 case 0x1c2: 6744 case 0x1c4 ... 0x1c6: 6745 case 0x1d0 ... 0x1fe: 6746 disas_insn_new(s, cpu, b); 6747 break; 6748 default: 6749 goto unknown_op; 6750 } 6751 return true; 6752 illegal_op: 6753 gen_illegal_opcode(s); 6754 return true; 6755 unknown_op: 6756 gen_unknown_opcode(env, s); 6757 return true; 6758 } 6759 6760 void tcg_x86_init(void) 6761 { 6762 static const char reg_names[CPU_NB_REGS][4] = { 6763 #ifdef TARGET_X86_64 6764 [R_EAX] = "rax", 6765 [R_EBX] = "rbx", 6766 [R_ECX] = "rcx", 6767 [R_EDX] = "rdx", 6768 [R_ESI] = "rsi", 6769 [R_EDI] = "rdi", 6770 [R_EBP] = "rbp", 6771 [R_ESP] = "rsp", 6772 [8] = "r8", 6773 [9] = "r9", 6774 [10] = "r10", 6775 [11] = "r11", 6776 [12] = "r12", 6777 [13] = "r13", 6778 [14] = "r14", 6779 [15] = "r15", 6780 #else 6781 [R_EAX] = "eax", 6782 [R_EBX] = "ebx", 6783 [R_ECX] = "ecx", 6784 [R_EDX] = "edx", 6785 [R_ESI] = "esi", 6786 [R_EDI] = "edi", 6787 [R_EBP] = "ebp", 6788 [R_ESP] = "esp", 6789 #endif 6790 }; 6791 static const char eip_name[] = { 6792 #ifdef TARGET_X86_64 6793 "rip" 6794 #else 6795 "eip" 6796 #endif 6797 }; 6798 static const char seg_base_names[6][8] = { 6799 [R_CS] = "cs_base", 6800 [R_DS] = "ds_base", 6801 [R_ES] = "es_base", 6802 [R_FS] = "fs_base", 6803 [R_GS] = "gs_base", 6804 [R_SS] = "ss_base", 6805 }; 6806 static const char bnd_regl_names[4][8] = { 6807 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb" 6808 }; 6809 static const char bnd_regu_names[4][8] = { 6810 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" 6811 }; 6812 int i; 6813 6814 cpu_cc_op = tcg_global_mem_new_i32(cpu_env, 6815 offsetof(CPUX86State, cc_op), "cc_op"); 6816 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst), 6817 "cc_dst"); 6818 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src), 6819 "cc_src"); 6820 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2), 6821 "cc_src2"); 6822 cpu_eip = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, eip), eip_name); 6823 6824 for (i = 0; i < CPU_NB_REGS; ++i) { 6825 cpu_regs[i] = tcg_global_mem_new(cpu_env, 6826 offsetof(CPUX86State, regs[i]), 6827 reg_names[i]); 6828 } 6829 6830 for (i = 0; i < 6; ++i) { 6831 cpu_seg_base[i] 6832 = tcg_global_mem_new(cpu_env, 6833 offsetof(CPUX86State, segs[i].base), 6834 seg_base_names[i]); 6835 } 6836 6837 for (i = 0; i < 4; ++i) { 6838 cpu_bndl[i] 6839 = tcg_global_mem_new_i64(cpu_env, 6840 offsetof(CPUX86State, bnd_regs[i].lb), 6841 bnd_regl_names[i]); 6842 cpu_bndu[i] 6843 = tcg_global_mem_new_i64(cpu_env, 6844 offsetof(CPUX86State, bnd_regs[i].ub), 6845 bnd_regu_names[i]); 6846 } 6847 } 6848 6849 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 6850 { 6851 DisasContext *dc = container_of(dcbase, DisasContext, base); 6852 CPUX86State *env = cpu->env_ptr; 6853 uint32_t flags = dc->base.tb->flags; 6854 uint32_t cflags = tb_cflags(dc->base.tb); 6855 int cpl = (flags >> HF_CPL_SHIFT) & 3; 6856 int iopl = (flags >> IOPL_SHIFT) & 3; 6857 6858 dc->cs_base = dc->base.tb->cs_base; 6859 dc->pc_save = dc->base.pc_next; 6860 dc->flags = flags; 6861 #ifndef CONFIG_USER_ONLY 6862 dc->cpl = cpl; 6863 dc->iopl = iopl; 6864 #endif 6865 6866 /* We make some simplifying assumptions; validate they're correct. */ 6867 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); 6868 g_assert(CPL(dc) == cpl); 6869 g_assert(IOPL(dc) == iopl); 6870 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0)); 6871 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0)); 6872 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0)); 6873 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0)); 6874 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0)); 6875 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0)); 6876 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0)); 6877 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0)); 6878 6879 dc->cc_op = CC_OP_DYNAMIC; 6880 dc->cc_op_dirty = false; 6881 dc->popl_esp_hack = 0; 6882 /* select memory access functions */ 6883 dc->mem_index = 0; 6884 #ifdef CONFIG_SOFTMMU 6885 dc->mem_index = cpu_mmu_index(env, false); 6886 #endif 6887 dc->cpuid_features = env->features[FEAT_1_EDX]; 6888 dc->cpuid_ext_features = env->features[FEAT_1_ECX]; 6889 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; 6890 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; 6891 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; 6892 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX]; 6893 dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; 6894 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || 6895 (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 6896 /* 6897 * If jmp_opt, we want to handle each string instruction individually. 6898 * For icount also disable repz optimization so that each iteration 6899 * is accounted separately. 6900 */ 6901 dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT); 6902 6903 dc->T0 = tcg_temp_new(); 6904 dc->T1 = tcg_temp_new(); 6905 dc->A0 = tcg_temp_new(); 6906 6907 dc->tmp0 = tcg_temp_new(); 6908 dc->tmp1_i64 = tcg_temp_new_i64(); 6909 dc->tmp2_i32 = tcg_temp_new_i32(); 6910 dc->tmp3_i32 = tcg_temp_new_i32(); 6911 dc->tmp4 = tcg_temp_new(); 6912 dc->cc_srcT = tcg_temp_local_new(); 6913 } 6914 6915 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) 6916 { 6917 } 6918 6919 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 6920 { 6921 DisasContext *dc = container_of(dcbase, DisasContext, base); 6922 target_ulong pc_arg = dc->base.pc_next; 6923 6924 dc->prev_insn_end = tcg_last_op(); 6925 if (TARGET_TB_PCREL) { 6926 pc_arg -= dc->cs_base; 6927 pc_arg &= ~TARGET_PAGE_MASK; 6928 } 6929 tcg_gen_insn_start(pc_arg, dc->cc_op); 6930 } 6931 6932 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 6933 { 6934 DisasContext *dc = container_of(dcbase, DisasContext, base); 6935 6936 #ifdef TARGET_VSYSCALL_PAGE 6937 /* 6938 * Detect entry into the vsyscall page and invoke the syscall. 6939 */ 6940 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) { 6941 gen_exception(dc, EXCP_VSYSCALL); 6942 dc->base.pc_next = dc->pc + 1; 6943 return; 6944 } 6945 #endif 6946 6947 if (disas_insn(dc, cpu)) { 6948 target_ulong pc_next = dc->pc; 6949 dc->base.pc_next = pc_next; 6950 6951 if (dc->base.is_jmp == DISAS_NEXT) { 6952 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) { 6953 /* 6954 * If single step mode, we generate only one instruction and 6955 * generate an exception. 6956 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 6957 * the flag and abort the translation to give the irqs a 6958 * chance to happen. 6959 */ 6960 dc->base.is_jmp = DISAS_EOB_NEXT; 6961 } else if (!is_same_page(&dc->base, pc_next)) { 6962 dc->base.is_jmp = DISAS_TOO_MANY; 6963 } 6964 } 6965 } 6966 } 6967 6968 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 6969 { 6970 DisasContext *dc = container_of(dcbase, DisasContext, base); 6971 6972 switch (dc->base.is_jmp) { 6973 case DISAS_NORETURN: 6974 break; 6975 case DISAS_TOO_MANY: 6976 gen_update_cc_op(dc); 6977 gen_jmp_rel_csize(dc, 0, 0); 6978 break; 6979 case DISAS_EOB_NEXT: 6980 gen_update_cc_op(dc); 6981 gen_update_eip_cur(dc); 6982 /* fall through */ 6983 case DISAS_EOB_ONLY: 6984 gen_eob(dc); 6985 break; 6986 case DISAS_EOB_INHIBIT_IRQ: 6987 gen_update_cc_op(dc); 6988 gen_update_eip_cur(dc); 6989 gen_eob_inhibit_irq(dc, true); 6990 break; 6991 case DISAS_JUMP: 6992 gen_jr(dc); 6993 break; 6994 default: 6995 g_assert_not_reached(); 6996 } 6997 } 6998 6999 static void i386_tr_disas_log(const DisasContextBase *dcbase, 7000 CPUState *cpu, FILE *logfile) 7001 { 7002 DisasContext *dc = container_of(dcbase, DisasContext, base); 7003 7004 fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first)); 7005 target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size); 7006 } 7007 7008 static const TranslatorOps i386_tr_ops = { 7009 .init_disas_context = i386_tr_init_disas_context, 7010 .tb_start = i386_tr_tb_start, 7011 .insn_start = i386_tr_insn_start, 7012 .translate_insn = i386_tr_translate_insn, 7013 .tb_stop = i386_tr_tb_stop, 7014 .disas_log = i386_tr_disas_log, 7015 }; 7016 7017 /* generate intermediate code for basic block 'tb'. */ 7018 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns, 7019 target_ulong pc, void *host_pc) 7020 { 7021 DisasContext dc; 7022 7023 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); 7024 } 7025 7026 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, 7027 target_ulong *data) 7028 { 7029 int cc_op = data[1]; 7030 7031 if (TARGET_TB_PCREL) { 7032 env->eip = (env->eip & TARGET_PAGE_MASK) | data[0]; 7033 } else { 7034 env->eip = data[0] - tb->cs_base; 7035 } 7036 if (cc_op != CC_OP_DYNAMIC) { 7037 env->cc_op = cc_op; 7038 } 7039 } 7040