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