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 static void gen_set_eflags(DisasContext *s, target_ulong mask) 2750 { 2751 TCGv t = tcg_temp_new(); 2752 2753 tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags)); 2754 tcg_gen_ori_tl(t, t, mask); 2755 tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags)); 2756 tcg_temp_free(t); 2757 } 2758 2759 static void gen_reset_eflags(DisasContext *s, target_ulong mask) 2760 { 2761 TCGv t = tcg_temp_new(); 2762 2763 tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags)); 2764 tcg_gen_andi_tl(t, t, ~mask); 2765 tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags)); 2766 tcg_temp_free(t); 2767 } 2768 2769 /* Clear BND registers during legacy branches. */ 2770 static void gen_bnd_jmp(DisasContext *s) 2771 { 2772 /* Clear the registers only if BND prefix is missing, MPX is enabled, 2773 and if the BNDREGs are known to be in use (non-zero) already. 2774 The helper itself will check BNDPRESERVE at runtime. */ 2775 if ((s->prefix & PREFIX_REPNZ) == 0 2776 && (s->flags & HF_MPX_EN_MASK) != 0 2777 && (s->flags & HF_MPX_IU_MASK) != 0) { 2778 gen_helper_bnd_jmp(cpu_env); 2779 } 2780 } 2781 2782 /* Generate an end of block. Trace exception is also generated if needed. 2783 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. 2784 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of 2785 S->TF. This is used by the syscall/sysret insns. */ 2786 static void 2787 do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr) 2788 { 2789 gen_update_cc_op(s); 2790 2791 /* If several instructions disable interrupts, only the first does it. */ 2792 if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) { 2793 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); 2794 } else { 2795 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); 2796 } 2797 2798 if (s->base.tb->flags & HF_RF_MASK) { 2799 gen_reset_eflags(s, RF_MASK); 2800 } 2801 if (recheck_tf) { 2802 gen_helper_rechecking_single_step(cpu_env); 2803 tcg_gen_exit_tb(NULL, 0); 2804 } else if (s->flags & HF_TF_MASK) { 2805 gen_helper_single_step(cpu_env); 2806 } else if (jr) { 2807 tcg_gen_lookup_and_goto_ptr(); 2808 } else { 2809 tcg_gen_exit_tb(NULL, 0); 2810 } 2811 s->base.is_jmp = DISAS_NORETURN; 2812 } 2813 2814 static inline void 2815 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf) 2816 { 2817 do_gen_eob_worker(s, inhibit, recheck_tf, false); 2818 } 2819 2820 /* End of block. 2821 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */ 2822 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit) 2823 { 2824 gen_eob_worker(s, inhibit, false); 2825 } 2826 2827 /* End of block, resetting the inhibit irq flag. */ 2828 static void gen_eob(DisasContext *s) 2829 { 2830 gen_eob_worker(s, false, false); 2831 } 2832 2833 /* Jump to register */ 2834 static void gen_jr(DisasContext *s) 2835 { 2836 do_gen_eob_worker(s, false, false, true); 2837 } 2838 2839 /* Jump to eip+diff, truncating the result to OT. */ 2840 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num) 2841 { 2842 bool use_goto_tb = s->jmp_opt; 2843 target_ulong mask = -1; 2844 target_ulong new_pc = s->pc + diff; 2845 target_ulong new_eip = new_pc - s->cs_base; 2846 2847 /* In 64-bit mode, operand size is fixed at 64 bits. */ 2848 if (!CODE64(s)) { 2849 if (ot == MO_16) { 2850 mask = 0xffff; 2851 if (TARGET_TB_PCREL && CODE32(s)) { 2852 use_goto_tb = false; 2853 } 2854 } else { 2855 mask = 0xffffffff; 2856 } 2857 } 2858 new_eip &= mask; 2859 2860 gen_update_cc_op(s); 2861 set_cc_op(s, CC_OP_DYNAMIC); 2862 2863 if (TARGET_TB_PCREL) { 2864 tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save); 2865 /* 2866 * If we can prove the branch does not leave the page and we have 2867 * no extra masking to apply (data16 branch in code32, see above), 2868 * then we have also proven that the addition does not wrap. 2869 */ 2870 if (!use_goto_tb || !is_same_page(&s->base, new_pc)) { 2871 tcg_gen_andi_tl(cpu_eip, cpu_eip, mask); 2872 use_goto_tb = false; 2873 } 2874 } 2875 2876 if (use_goto_tb && 2877 translator_use_goto_tb(&s->base, new_eip + s->cs_base)) { 2878 /* jump to same page: we can use a direct jump */ 2879 tcg_gen_goto_tb(tb_num); 2880 if (!TARGET_TB_PCREL) { 2881 tcg_gen_movi_tl(cpu_eip, new_eip); 2882 } 2883 tcg_gen_exit_tb(s->base.tb, tb_num); 2884 s->base.is_jmp = DISAS_NORETURN; 2885 } else { 2886 if (!TARGET_TB_PCREL) { 2887 tcg_gen_movi_tl(cpu_eip, new_eip); 2888 } 2889 if (s->jmp_opt) { 2890 gen_jr(s); /* jump to another page */ 2891 } else { 2892 gen_eob(s); /* exit to main loop */ 2893 } 2894 } 2895 } 2896 2897 /* Jump to eip+diff, truncating to the current code size. */ 2898 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num) 2899 { 2900 /* CODE64 ignores the OT argument, so we need not consider it. */ 2901 gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num); 2902 } 2903 2904 static inline void gen_ldq_env_A0(DisasContext *s, int offset) 2905 { 2906 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2907 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset); 2908 } 2909 2910 static inline void gen_stq_env_A0(DisasContext *s, int offset) 2911 { 2912 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset); 2913 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2914 } 2915 2916 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align) 2917 { 2918 int mem_index = s->mem_index; 2919 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index, 2920 MO_LEUQ | (align ? MO_ALIGN_16 : 0)); 2921 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0))); 2922 tcg_gen_addi_tl(s->tmp0, s->A0, 8); 2923 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2924 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1))); 2925 } 2926 2927 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align) 2928 { 2929 int mem_index = s->mem_index; 2930 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0))); 2931 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, 2932 MO_LEUQ | (align ? MO_ALIGN_16 : 0)); 2933 tcg_gen_addi_tl(s->tmp0, s->A0, 8); 2934 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1))); 2935 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2936 } 2937 2938 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align) 2939 { 2940 int mem_index = s->mem_index; 2941 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index, 2942 MO_LEUQ | (align ? MO_ALIGN_32 : 0)); 2943 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(0))); 2944 tcg_gen_addi_tl(s->tmp0, s->A0, 8); 2945 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2946 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(1))); 2947 2948 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2949 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2950 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(2))); 2951 tcg_gen_addi_tl(s->tmp0, s->A0, 24); 2952 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2953 tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(3))); 2954 } 2955 2956 static void gen_sty_env_A0(DisasContext *s, int offset, bool align) 2957 { 2958 int mem_index = s->mem_index; 2959 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(0))); 2960 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, 2961 MO_LEUQ | (align ? MO_ALIGN_32 : 0)); 2962 tcg_gen_addi_tl(s->tmp0, s->A0, 8); 2963 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(1))); 2964 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2965 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2966 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(2))); 2967 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2968 tcg_gen_addi_tl(s->tmp0, s->A0, 24); 2969 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(3))); 2970 tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); 2971 } 2972 2973 #include "decode-new.h" 2974 #include "emit.c.inc" 2975 #include "decode-new.c.inc" 2976 2977 /* convert one instruction. s->base.is_jmp is set if the translation must 2978 be stopped. Return the next pc value */ 2979 static bool disas_insn(DisasContext *s, CPUState *cpu) 2980 { 2981 CPUX86State *env = cpu->env_ptr; 2982 int b, prefixes; 2983 int shift; 2984 MemOp ot, aflag, dflag; 2985 int modrm, reg, rm, mod, op, opreg, val; 2986 bool orig_cc_op_dirty = s->cc_op_dirty; 2987 CCOp orig_cc_op = s->cc_op; 2988 target_ulong orig_pc_save = s->pc_save; 2989 2990 s->pc = s->base.pc_next; 2991 s->override = -1; 2992 #ifdef TARGET_X86_64 2993 s->rex_r = 0; 2994 s->rex_x = 0; 2995 s->rex_b = 0; 2996 #endif 2997 s->rip_offset = 0; /* for relative ip address */ 2998 s->vex_l = 0; 2999 s->vex_v = 0; 3000 s->vex_w = false; 3001 switch (sigsetjmp(s->jmpbuf, 0)) { 3002 case 0: 3003 break; 3004 case 1: 3005 gen_exception_gpf(s); 3006 return true; 3007 case 2: 3008 /* Restore state that may affect the next instruction. */ 3009 s->pc = s->base.pc_next; 3010 /* 3011 * TODO: These save/restore can be removed after the table-based 3012 * decoder is complete; we will be decoding the insn completely 3013 * before any code generation that might affect these variables. 3014 */ 3015 s->cc_op_dirty = orig_cc_op_dirty; 3016 s->cc_op = orig_cc_op; 3017 s->pc_save = orig_pc_save; 3018 /* END TODO */ 3019 s->base.num_insns--; 3020 tcg_remove_ops_after(s->prev_insn_end); 3021 s->base.is_jmp = DISAS_TOO_MANY; 3022 return false; 3023 default: 3024 g_assert_not_reached(); 3025 } 3026 3027 prefixes = 0; 3028 3029 next_byte: 3030 s->prefix = prefixes; 3031 b = x86_ldub_code(env, s); 3032 /* Collect prefixes. */ 3033 switch (b) { 3034 default: 3035 break; 3036 case 0x0f: 3037 b = x86_ldub_code(env, s) + 0x100; 3038 break; 3039 case 0xf3: 3040 prefixes |= PREFIX_REPZ; 3041 prefixes &= ~PREFIX_REPNZ; 3042 goto next_byte; 3043 case 0xf2: 3044 prefixes |= PREFIX_REPNZ; 3045 prefixes &= ~PREFIX_REPZ; 3046 goto next_byte; 3047 case 0xf0: 3048 prefixes |= PREFIX_LOCK; 3049 goto next_byte; 3050 case 0x2e: 3051 s->override = R_CS; 3052 goto next_byte; 3053 case 0x36: 3054 s->override = R_SS; 3055 goto next_byte; 3056 case 0x3e: 3057 s->override = R_DS; 3058 goto next_byte; 3059 case 0x26: 3060 s->override = R_ES; 3061 goto next_byte; 3062 case 0x64: 3063 s->override = R_FS; 3064 goto next_byte; 3065 case 0x65: 3066 s->override = R_GS; 3067 goto next_byte; 3068 case 0x66: 3069 prefixes |= PREFIX_DATA; 3070 goto next_byte; 3071 case 0x67: 3072 prefixes |= PREFIX_ADR; 3073 goto next_byte; 3074 #ifdef TARGET_X86_64 3075 case 0x40 ... 0x4f: 3076 if (CODE64(s)) { 3077 /* REX prefix */ 3078 prefixes |= PREFIX_REX; 3079 s->vex_w = (b >> 3) & 1; 3080 s->rex_r = (b & 0x4) << 1; 3081 s->rex_x = (b & 0x2) << 2; 3082 s->rex_b = (b & 0x1) << 3; 3083 goto next_byte; 3084 } 3085 break; 3086 #endif 3087 case 0xc5: /* 2-byte VEX */ 3088 case 0xc4: /* 3-byte VEX */ 3089 if (CODE32(s) && !VM86(s)) { 3090 int vex2 = x86_ldub_code(env, s); 3091 s->pc--; /* rewind the advance_pc() x86_ldub_code() did */ 3092 3093 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) { 3094 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b, 3095 otherwise the instruction is LES or LDS. */ 3096 break; 3097 } 3098 disas_insn_new(s, cpu, b); 3099 return s->pc; 3100 } 3101 break; 3102 } 3103 3104 /* Post-process prefixes. */ 3105 if (CODE64(s)) { 3106 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit 3107 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence 3108 over 0x66 if both are present. */ 3109 dflag = (REX_W(s) ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32); 3110 /* In 64-bit mode, 0x67 selects 32-bit addressing. */ 3111 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64); 3112 } else { 3113 /* In 16/32-bit mode, 0x66 selects the opposite data size. */ 3114 if (CODE32(s) ^ ((prefixes & PREFIX_DATA) != 0)) { 3115 dflag = MO_32; 3116 } else { 3117 dflag = MO_16; 3118 } 3119 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */ 3120 if (CODE32(s) ^ ((prefixes & PREFIX_ADR) != 0)) { 3121 aflag = MO_32; 3122 } else { 3123 aflag = MO_16; 3124 } 3125 } 3126 3127 s->prefix = prefixes; 3128 s->aflag = aflag; 3129 s->dflag = dflag; 3130 3131 /* now check op code */ 3132 switch (b) { 3133 /**************************/ 3134 /* arith & logic */ 3135 case 0x00 ... 0x05: 3136 case 0x08 ... 0x0d: 3137 case 0x10 ... 0x15: 3138 case 0x18 ... 0x1d: 3139 case 0x20 ... 0x25: 3140 case 0x28 ... 0x2d: 3141 case 0x30 ... 0x35: 3142 case 0x38 ... 0x3d: 3143 { 3144 int op, f, val; 3145 op = (b >> 3) & 7; 3146 f = (b >> 1) & 3; 3147 3148 ot = mo_b_d(b, dflag); 3149 3150 switch(f) { 3151 case 0: /* OP Ev, Gv */ 3152 modrm = x86_ldub_code(env, s); 3153 reg = ((modrm >> 3) & 7) | REX_R(s); 3154 mod = (modrm >> 6) & 3; 3155 rm = (modrm & 7) | REX_B(s); 3156 if (mod != 3) { 3157 gen_lea_modrm(env, s, modrm); 3158 opreg = OR_TMP0; 3159 } else if (op == OP_XORL && rm == reg) { 3160 xor_zero: 3161 /* xor reg, reg optimisation */ 3162 set_cc_op(s, CC_OP_CLR); 3163 tcg_gen_movi_tl(s->T0, 0); 3164 gen_op_mov_reg_v(s, ot, reg, s->T0); 3165 break; 3166 } else { 3167 opreg = rm; 3168 } 3169 gen_op_mov_v_reg(s, ot, s->T1, reg); 3170 gen_op(s, op, ot, opreg); 3171 break; 3172 case 1: /* OP Gv, Ev */ 3173 modrm = x86_ldub_code(env, s); 3174 mod = (modrm >> 6) & 3; 3175 reg = ((modrm >> 3) & 7) | REX_R(s); 3176 rm = (modrm & 7) | REX_B(s); 3177 if (mod != 3) { 3178 gen_lea_modrm(env, s, modrm); 3179 gen_op_ld_v(s, ot, s->T1, s->A0); 3180 } else if (op == OP_XORL && rm == reg) { 3181 goto xor_zero; 3182 } else { 3183 gen_op_mov_v_reg(s, ot, s->T1, rm); 3184 } 3185 gen_op(s, op, ot, reg); 3186 break; 3187 case 2: /* OP A, Iv */ 3188 val = insn_get(env, s, ot); 3189 tcg_gen_movi_tl(s->T1, val); 3190 gen_op(s, op, ot, OR_EAX); 3191 break; 3192 } 3193 } 3194 break; 3195 3196 case 0x82: 3197 if (CODE64(s)) 3198 goto illegal_op; 3199 /* fall through */ 3200 case 0x80: /* GRP1 */ 3201 case 0x81: 3202 case 0x83: 3203 { 3204 int val; 3205 3206 ot = mo_b_d(b, dflag); 3207 3208 modrm = x86_ldub_code(env, s); 3209 mod = (modrm >> 6) & 3; 3210 rm = (modrm & 7) | REX_B(s); 3211 op = (modrm >> 3) & 7; 3212 3213 if (mod != 3) { 3214 if (b == 0x83) 3215 s->rip_offset = 1; 3216 else 3217 s->rip_offset = insn_const_size(ot); 3218 gen_lea_modrm(env, s, modrm); 3219 opreg = OR_TMP0; 3220 } else { 3221 opreg = rm; 3222 } 3223 3224 switch(b) { 3225 default: 3226 case 0x80: 3227 case 0x81: 3228 case 0x82: 3229 val = insn_get(env, s, ot); 3230 break; 3231 case 0x83: 3232 val = (int8_t)insn_get(env, s, MO_8); 3233 break; 3234 } 3235 tcg_gen_movi_tl(s->T1, val); 3236 gen_op(s, op, ot, opreg); 3237 } 3238 break; 3239 3240 /**************************/ 3241 /* inc, dec, and other misc arith */ 3242 case 0x40 ... 0x47: /* inc Gv */ 3243 ot = dflag; 3244 gen_inc(s, ot, OR_EAX + (b & 7), 1); 3245 break; 3246 case 0x48 ... 0x4f: /* dec Gv */ 3247 ot = dflag; 3248 gen_inc(s, ot, OR_EAX + (b & 7), -1); 3249 break; 3250 case 0xf6: /* GRP3 */ 3251 case 0xf7: 3252 ot = mo_b_d(b, dflag); 3253 3254 modrm = x86_ldub_code(env, s); 3255 mod = (modrm >> 6) & 3; 3256 rm = (modrm & 7) | REX_B(s); 3257 op = (modrm >> 3) & 7; 3258 if (mod != 3) { 3259 if (op == 0) { 3260 s->rip_offset = insn_const_size(ot); 3261 } 3262 gen_lea_modrm(env, s, modrm); 3263 /* For those below that handle locked memory, don't load here. */ 3264 if (!(s->prefix & PREFIX_LOCK) 3265 || op != 2) { 3266 gen_op_ld_v(s, ot, s->T0, s->A0); 3267 } 3268 } else { 3269 gen_op_mov_v_reg(s, ot, s->T0, rm); 3270 } 3271 3272 switch(op) { 3273 case 0: /* test */ 3274 val = insn_get(env, s, ot); 3275 tcg_gen_movi_tl(s->T1, val); 3276 gen_op_testl_T0_T1_cc(s); 3277 set_cc_op(s, CC_OP_LOGICB + ot); 3278 break; 3279 case 2: /* not */ 3280 if (s->prefix & PREFIX_LOCK) { 3281 if (mod == 3) { 3282 goto illegal_op; 3283 } 3284 tcg_gen_movi_tl(s->T0, ~0); 3285 tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0, 3286 s->mem_index, ot | MO_LE); 3287 } else { 3288 tcg_gen_not_tl(s->T0, s->T0); 3289 if (mod != 3) { 3290 gen_op_st_v(s, ot, s->T0, s->A0); 3291 } else { 3292 gen_op_mov_reg_v(s, ot, rm, s->T0); 3293 } 3294 } 3295 break; 3296 case 3: /* neg */ 3297 if (s->prefix & PREFIX_LOCK) { 3298 TCGLabel *label1; 3299 TCGv a0, t0, t1, t2; 3300 3301 if (mod == 3) { 3302 goto illegal_op; 3303 } 3304 a0 = tcg_temp_local_new(); 3305 t0 = tcg_temp_local_new(); 3306 label1 = gen_new_label(); 3307 3308 tcg_gen_mov_tl(a0, s->A0); 3309 tcg_gen_mov_tl(t0, s->T0); 3310 3311 gen_set_label(label1); 3312 t1 = tcg_temp_new(); 3313 t2 = tcg_temp_new(); 3314 tcg_gen_mov_tl(t2, t0); 3315 tcg_gen_neg_tl(t1, t0); 3316 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1, 3317 s->mem_index, ot | MO_LE); 3318 tcg_temp_free(t1); 3319 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1); 3320 3321 tcg_temp_free(t2); 3322 tcg_temp_free(a0); 3323 tcg_gen_mov_tl(s->T0, t0); 3324 tcg_temp_free(t0); 3325 } else { 3326 tcg_gen_neg_tl(s->T0, s->T0); 3327 if (mod != 3) { 3328 gen_op_st_v(s, ot, s->T0, s->A0); 3329 } else { 3330 gen_op_mov_reg_v(s, ot, rm, s->T0); 3331 } 3332 } 3333 gen_op_update_neg_cc(s); 3334 set_cc_op(s, CC_OP_SUBB + ot); 3335 break; 3336 case 4: /* mul */ 3337 switch(ot) { 3338 case MO_8: 3339 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX); 3340 tcg_gen_ext8u_tl(s->T0, s->T0); 3341 tcg_gen_ext8u_tl(s->T1, s->T1); 3342 /* XXX: use 32 bit mul which could be faster */ 3343 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3344 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3345 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3346 tcg_gen_andi_tl(cpu_cc_src, s->T0, 0xff00); 3347 set_cc_op(s, CC_OP_MULB); 3348 break; 3349 case MO_16: 3350 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX); 3351 tcg_gen_ext16u_tl(s->T0, s->T0); 3352 tcg_gen_ext16u_tl(s->T1, s->T1); 3353 /* XXX: use 32 bit mul which could be faster */ 3354 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3355 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3356 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3357 tcg_gen_shri_tl(s->T0, s->T0, 16); 3358 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); 3359 tcg_gen_mov_tl(cpu_cc_src, s->T0); 3360 set_cc_op(s, CC_OP_MULW); 3361 break; 3362 default: 3363 case MO_32: 3364 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3365 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]); 3366 tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32, 3367 s->tmp2_i32, s->tmp3_i32); 3368 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32); 3369 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32); 3370 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 3371 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]); 3372 set_cc_op(s, CC_OP_MULL); 3373 break; 3374 #ifdef TARGET_X86_64 3375 case MO_64: 3376 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX], 3377 s->T0, cpu_regs[R_EAX]); 3378 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 3379 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]); 3380 set_cc_op(s, CC_OP_MULQ); 3381 break; 3382 #endif 3383 } 3384 break; 3385 case 5: /* imul */ 3386 switch(ot) { 3387 case MO_8: 3388 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX); 3389 tcg_gen_ext8s_tl(s->T0, s->T0); 3390 tcg_gen_ext8s_tl(s->T1, s->T1); 3391 /* XXX: use 32 bit mul which could be faster */ 3392 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3393 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3394 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3395 tcg_gen_ext8s_tl(s->tmp0, s->T0); 3396 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0); 3397 set_cc_op(s, CC_OP_MULB); 3398 break; 3399 case MO_16: 3400 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX); 3401 tcg_gen_ext16s_tl(s->T0, s->T0); 3402 tcg_gen_ext16s_tl(s->T1, s->T1); 3403 /* XXX: use 32 bit mul which could be faster */ 3404 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3405 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3406 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3407 tcg_gen_ext16s_tl(s->tmp0, s->T0); 3408 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0); 3409 tcg_gen_shri_tl(s->T0, s->T0, 16); 3410 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); 3411 set_cc_op(s, CC_OP_MULW); 3412 break; 3413 default: 3414 case MO_32: 3415 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3416 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]); 3417 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32, 3418 s->tmp2_i32, s->tmp3_i32); 3419 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32); 3420 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32); 3421 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31); 3422 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 3423 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32); 3424 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32); 3425 set_cc_op(s, CC_OP_MULL); 3426 break; 3427 #ifdef TARGET_X86_64 3428 case MO_64: 3429 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX], 3430 s->T0, cpu_regs[R_EAX]); 3431 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); 3432 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63); 3433 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]); 3434 set_cc_op(s, CC_OP_MULQ); 3435 break; 3436 #endif 3437 } 3438 break; 3439 case 6: /* div */ 3440 switch(ot) { 3441 case MO_8: 3442 gen_helper_divb_AL(cpu_env, s->T0); 3443 break; 3444 case MO_16: 3445 gen_helper_divw_AX(cpu_env, s->T0); 3446 break; 3447 default: 3448 case MO_32: 3449 gen_helper_divl_EAX(cpu_env, s->T0); 3450 break; 3451 #ifdef TARGET_X86_64 3452 case MO_64: 3453 gen_helper_divq_EAX(cpu_env, s->T0); 3454 break; 3455 #endif 3456 } 3457 break; 3458 case 7: /* idiv */ 3459 switch(ot) { 3460 case MO_8: 3461 gen_helper_idivb_AL(cpu_env, s->T0); 3462 break; 3463 case MO_16: 3464 gen_helper_idivw_AX(cpu_env, s->T0); 3465 break; 3466 default: 3467 case MO_32: 3468 gen_helper_idivl_EAX(cpu_env, s->T0); 3469 break; 3470 #ifdef TARGET_X86_64 3471 case MO_64: 3472 gen_helper_idivq_EAX(cpu_env, s->T0); 3473 break; 3474 #endif 3475 } 3476 break; 3477 default: 3478 goto unknown_op; 3479 } 3480 break; 3481 3482 case 0xfe: /* GRP4 */ 3483 case 0xff: /* GRP5 */ 3484 ot = mo_b_d(b, dflag); 3485 3486 modrm = x86_ldub_code(env, s); 3487 mod = (modrm >> 6) & 3; 3488 rm = (modrm & 7) | REX_B(s); 3489 op = (modrm >> 3) & 7; 3490 if (op >= 2 && b == 0xfe) { 3491 goto unknown_op; 3492 } 3493 if (CODE64(s)) { 3494 if (op == 2 || op == 4) { 3495 /* operand size for jumps is 64 bit */ 3496 ot = MO_64; 3497 } else if (op == 3 || op == 5) { 3498 ot = dflag != MO_16 ? MO_32 + REX_W(s) : MO_16; 3499 } else if (op == 6) { 3500 /* default push size is 64 bit */ 3501 ot = mo_pushpop(s, dflag); 3502 } 3503 } 3504 if (mod != 3) { 3505 gen_lea_modrm(env, s, modrm); 3506 if (op >= 2 && op != 3 && op != 5) 3507 gen_op_ld_v(s, ot, s->T0, s->A0); 3508 } else { 3509 gen_op_mov_v_reg(s, ot, s->T0, rm); 3510 } 3511 3512 switch(op) { 3513 case 0: /* inc Ev */ 3514 if (mod != 3) 3515 opreg = OR_TMP0; 3516 else 3517 opreg = rm; 3518 gen_inc(s, ot, opreg, 1); 3519 break; 3520 case 1: /* dec Ev */ 3521 if (mod != 3) 3522 opreg = OR_TMP0; 3523 else 3524 opreg = rm; 3525 gen_inc(s, ot, opreg, -1); 3526 break; 3527 case 2: /* call Ev */ 3528 /* XXX: optimize if memory (no 'and' is necessary) */ 3529 if (dflag == MO_16) { 3530 tcg_gen_ext16u_tl(s->T0, s->T0); 3531 } 3532 gen_push_v(s, eip_next_tl(s)); 3533 gen_op_jmp_v(s, s->T0); 3534 gen_bnd_jmp(s); 3535 s->base.is_jmp = DISAS_JUMP; 3536 break; 3537 case 3: /* lcall Ev */ 3538 if (mod == 3) { 3539 goto illegal_op; 3540 } 3541 gen_op_ld_v(s, ot, s->T1, s->A0); 3542 gen_add_A0_im(s, 1 << ot); 3543 gen_op_ld_v(s, MO_16, s->T0, s->A0); 3544 do_lcall: 3545 if (PE(s) && !VM86(s)) { 3546 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3547 gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1, 3548 tcg_constant_i32(dflag - 1), 3549 eip_next_tl(s)); 3550 } else { 3551 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3552 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 3553 gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32, 3554 tcg_constant_i32(dflag - 1), 3555 eip_next_i32(s)); 3556 } 3557 s->base.is_jmp = DISAS_JUMP; 3558 break; 3559 case 4: /* jmp Ev */ 3560 if (dflag == MO_16) { 3561 tcg_gen_ext16u_tl(s->T0, s->T0); 3562 } 3563 gen_op_jmp_v(s, s->T0); 3564 gen_bnd_jmp(s); 3565 s->base.is_jmp = DISAS_JUMP; 3566 break; 3567 case 5: /* ljmp Ev */ 3568 if (mod == 3) { 3569 goto illegal_op; 3570 } 3571 gen_op_ld_v(s, ot, s->T1, s->A0); 3572 gen_add_A0_im(s, 1 << ot); 3573 gen_op_ld_v(s, MO_16, s->T0, s->A0); 3574 do_ljmp: 3575 if (PE(s) && !VM86(s)) { 3576 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3577 gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1, 3578 eip_next_tl(s)); 3579 } else { 3580 gen_op_movl_seg_T0_vm(s, R_CS); 3581 gen_op_jmp_v(s, s->T1); 3582 } 3583 s->base.is_jmp = DISAS_JUMP; 3584 break; 3585 case 6: /* push Ev */ 3586 gen_push_v(s, s->T0); 3587 break; 3588 default: 3589 goto unknown_op; 3590 } 3591 break; 3592 3593 case 0x84: /* test Ev, Gv */ 3594 case 0x85: 3595 ot = mo_b_d(b, dflag); 3596 3597 modrm = x86_ldub_code(env, s); 3598 reg = ((modrm >> 3) & 7) | REX_R(s); 3599 3600 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3601 gen_op_mov_v_reg(s, ot, s->T1, reg); 3602 gen_op_testl_T0_T1_cc(s); 3603 set_cc_op(s, CC_OP_LOGICB + ot); 3604 break; 3605 3606 case 0xa8: /* test eAX, Iv */ 3607 case 0xa9: 3608 ot = mo_b_d(b, dflag); 3609 val = insn_get(env, s, ot); 3610 3611 gen_op_mov_v_reg(s, ot, s->T0, OR_EAX); 3612 tcg_gen_movi_tl(s->T1, val); 3613 gen_op_testl_T0_T1_cc(s); 3614 set_cc_op(s, CC_OP_LOGICB + ot); 3615 break; 3616 3617 case 0x98: /* CWDE/CBW */ 3618 switch (dflag) { 3619 #ifdef TARGET_X86_64 3620 case MO_64: 3621 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX); 3622 tcg_gen_ext32s_tl(s->T0, s->T0); 3623 gen_op_mov_reg_v(s, MO_64, R_EAX, s->T0); 3624 break; 3625 #endif 3626 case MO_32: 3627 gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX); 3628 tcg_gen_ext16s_tl(s->T0, s->T0); 3629 gen_op_mov_reg_v(s, MO_32, R_EAX, s->T0); 3630 break; 3631 case MO_16: 3632 gen_op_mov_v_reg(s, MO_8, s->T0, R_EAX); 3633 tcg_gen_ext8s_tl(s->T0, s->T0); 3634 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 3635 break; 3636 default: 3637 tcg_abort(); 3638 } 3639 break; 3640 case 0x99: /* CDQ/CWD */ 3641 switch (dflag) { 3642 #ifdef TARGET_X86_64 3643 case MO_64: 3644 gen_op_mov_v_reg(s, MO_64, s->T0, R_EAX); 3645 tcg_gen_sari_tl(s->T0, s->T0, 63); 3646 gen_op_mov_reg_v(s, MO_64, R_EDX, s->T0); 3647 break; 3648 #endif 3649 case MO_32: 3650 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX); 3651 tcg_gen_ext32s_tl(s->T0, s->T0); 3652 tcg_gen_sari_tl(s->T0, s->T0, 31); 3653 gen_op_mov_reg_v(s, MO_32, R_EDX, s->T0); 3654 break; 3655 case MO_16: 3656 gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX); 3657 tcg_gen_ext16s_tl(s->T0, s->T0); 3658 tcg_gen_sari_tl(s->T0, s->T0, 15); 3659 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); 3660 break; 3661 default: 3662 tcg_abort(); 3663 } 3664 break; 3665 case 0x1af: /* imul Gv, Ev */ 3666 case 0x69: /* imul Gv, Ev, I */ 3667 case 0x6b: 3668 ot = dflag; 3669 modrm = x86_ldub_code(env, s); 3670 reg = ((modrm >> 3) & 7) | REX_R(s); 3671 if (b == 0x69) 3672 s->rip_offset = insn_const_size(ot); 3673 else if (b == 0x6b) 3674 s->rip_offset = 1; 3675 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3676 if (b == 0x69) { 3677 val = insn_get(env, s, ot); 3678 tcg_gen_movi_tl(s->T1, val); 3679 } else if (b == 0x6b) { 3680 val = (int8_t)insn_get(env, s, MO_8); 3681 tcg_gen_movi_tl(s->T1, val); 3682 } else { 3683 gen_op_mov_v_reg(s, ot, s->T1, reg); 3684 } 3685 switch (ot) { 3686 #ifdef TARGET_X86_64 3687 case MO_64: 3688 tcg_gen_muls2_i64(cpu_regs[reg], s->T1, s->T0, s->T1); 3689 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]); 3690 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63); 3691 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, s->T1); 3692 break; 3693 #endif 3694 case MO_32: 3695 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3696 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 3697 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32, 3698 s->tmp2_i32, s->tmp3_i32); 3699 tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32); 3700 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31); 3701 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]); 3702 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32); 3703 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32); 3704 break; 3705 default: 3706 tcg_gen_ext16s_tl(s->T0, s->T0); 3707 tcg_gen_ext16s_tl(s->T1, s->T1); 3708 /* XXX: use 32 bit mul which could be faster */ 3709 tcg_gen_mul_tl(s->T0, s->T0, s->T1); 3710 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 3711 tcg_gen_ext16s_tl(s->tmp0, s->T0); 3712 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0); 3713 gen_op_mov_reg_v(s, ot, reg, s->T0); 3714 break; 3715 } 3716 set_cc_op(s, CC_OP_MULB + ot); 3717 break; 3718 case 0x1c0: 3719 case 0x1c1: /* xadd Ev, Gv */ 3720 ot = mo_b_d(b, dflag); 3721 modrm = x86_ldub_code(env, s); 3722 reg = ((modrm >> 3) & 7) | REX_R(s); 3723 mod = (modrm >> 6) & 3; 3724 gen_op_mov_v_reg(s, ot, s->T0, reg); 3725 if (mod == 3) { 3726 rm = (modrm & 7) | REX_B(s); 3727 gen_op_mov_v_reg(s, ot, s->T1, rm); 3728 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3729 gen_op_mov_reg_v(s, ot, reg, s->T1); 3730 gen_op_mov_reg_v(s, ot, rm, s->T0); 3731 } else { 3732 gen_lea_modrm(env, s, modrm); 3733 if (s->prefix & PREFIX_LOCK) { 3734 tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0, 3735 s->mem_index, ot | MO_LE); 3736 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3737 } else { 3738 gen_op_ld_v(s, ot, s->T1, s->A0); 3739 tcg_gen_add_tl(s->T0, s->T0, s->T1); 3740 gen_op_st_v(s, ot, s->T0, s->A0); 3741 } 3742 gen_op_mov_reg_v(s, ot, reg, s->T1); 3743 } 3744 gen_op_update2_cc(s); 3745 set_cc_op(s, CC_OP_ADDB + ot); 3746 break; 3747 case 0x1b0: 3748 case 0x1b1: /* cmpxchg Ev, Gv */ 3749 { 3750 TCGv oldv, newv, cmpv; 3751 3752 ot = mo_b_d(b, dflag); 3753 modrm = x86_ldub_code(env, s); 3754 reg = ((modrm >> 3) & 7) | REX_R(s); 3755 mod = (modrm >> 6) & 3; 3756 oldv = tcg_temp_new(); 3757 newv = tcg_temp_new(); 3758 cmpv = tcg_temp_new(); 3759 gen_op_mov_v_reg(s, ot, newv, reg); 3760 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]); 3761 3762 if (s->prefix & PREFIX_LOCK) { 3763 if (mod == 3) { 3764 goto illegal_op; 3765 } 3766 gen_lea_modrm(env, s, modrm); 3767 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv, 3768 s->mem_index, ot | MO_LE); 3769 gen_op_mov_reg_v(s, ot, R_EAX, oldv); 3770 } else { 3771 if (mod == 3) { 3772 rm = (modrm & 7) | REX_B(s); 3773 gen_op_mov_v_reg(s, ot, oldv, rm); 3774 } else { 3775 gen_lea_modrm(env, s, modrm); 3776 gen_op_ld_v(s, ot, oldv, s->A0); 3777 rm = 0; /* avoid warning */ 3778 } 3779 gen_extu(ot, oldv); 3780 gen_extu(ot, cmpv); 3781 /* store value = (old == cmp ? new : old); */ 3782 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv); 3783 if (mod == 3) { 3784 gen_op_mov_reg_v(s, ot, R_EAX, oldv); 3785 gen_op_mov_reg_v(s, ot, rm, newv); 3786 } else { 3787 /* Perform an unconditional store cycle like physical cpu; 3788 must be before changing accumulator to ensure 3789 idempotency if the store faults and the instruction 3790 is restarted */ 3791 gen_op_st_v(s, ot, newv, s->A0); 3792 gen_op_mov_reg_v(s, ot, R_EAX, oldv); 3793 } 3794 } 3795 tcg_gen_mov_tl(cpu_cc_src, oldv); 3796 tcg_gen_mov_tl(s->cc_srcT, cmpv); 3797 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv); 3798 set_cc_op(s, CC_OP_SUBB + ot); 3799 tcg_temp_free(oldv); 3800 tcg_temp_free(newv); 3801 tcg_temp_free(cmpv); 3802 } 3803 break; 3804 case 0x1c7: /* cmpxchg8b */ 3805 modrm = x86_ldub_code(env, s); 3806 mod = (modrm >> 6) & 3; 3807 switch ((modrm >> 3) & 7) { 3808 case 1: /* CMPXCHG8, CMPXCHG16 */ 3809 if (mod == 3) { 3810 goto illegal_op; 3811 } 3812 #ifdef TARGET_X86_64 3813 if (dflag == MO_64) { 3814 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) { 3815 goto illegal_op; 3816 } 3817 gen_lea_modrm(env, s, modrm); 3818 if ((s->prefix & PREFIX_LOCK) && 3819 (tb_cflags(s->base.tb) & CF_PARALLEL)) { 3820 gen_helper_cmpxchg16b(cpu_env, s->A0); 3821 } else { 3822 gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0); 3823 } 3824 set_cc_op(s, CC_OP_EFLAGS); 3825 break; 3826 } 3827 #endif 3828 if (!(s->cpuid_features & CPUID_CX8)) { 3829 goto illegal_op; 3830 } 3831 gen_lea_modrm(env, s, modrm); 3832 if ((s->prefix & PREFIX_LOCK) && 3833 (tb_cflags(s->base.tb) & CF_PARALLEL)) { 3834 gen_helper_cmpxchg8b(cpu_env, s->A0); 3835 } else { 3836 gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0); 3837 } 3838 set_cc_op(s, CC_OP_EFLAGS); 3839 break; 3840 3841 case 7: /* RDSEED */ 3842 case 6: /* RDRAND */ 3843 if (mod != 3 || 3844 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) || 3845 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { 3846 goto illegal_op; 3847 } 3848 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 3849 gen_io_start(); 3850 s->base.is_jmp = DISAS_TOO_MANY; 3851 } 3852 gen_helper_rdrand(s->T0, cpu_env); 3853 rm = (modrm & 7) | REX_B(s); 3854 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3855 set_cc_op(s, CC_OP_EFLAGS); 3856 break; 3857 3858 default: 3859 goto illegal_op; 3860 } 3861 break; 3862 3863 /**************************/ 3864 /* push/pop */ 3865 case 0x50 ... 0x57: /* push */ 3866 gen_op_mov_v_reg(s, MO_32, s->T0, (b & 7) | REX_B(s)); 3867 gen_push_v(s, s->T0); 3868 break; 3869 case 0x58 ... 0x5f: /* pop */ 3870 ot = gen_pop_T0(s); 3871 /* NOTE: order is important for pop %sp */ 3872 gen_pop_update(s, ot); 3873 gen_op_mov_reg_v(s, ot, (b & 7) | REX_B(s), s->T0); 3874 break; 3875 case 0x60: /* pusha */ 3876 if (CODE64(s)) 3877 goto illegal_op; 3878 gen_pusha(s); 3879 break; 3880 case 0x61: /* popa */ 3881 if (CODE64(s)) 3882 goto illegal_op; 3883 gen_popa(s); 3884 break; 3885 case 0x68: /* push Iv */ 3886 case 0x6a: 3887 ot = mo_pushpop(s, dflag); 3888 if (b == 0x68) 3889 val = insn_get(env, s, ot); 3890 else 3891 val = (int8_t)insn_get(env, s, MO_8); 3892 tcg_gen_movi_tl(s->T0, val); 3893 gen_push_v(s, s->T0); 3894 break; 3895 case 0x8f: /* pop Ev */ 3896 modrm = x86_ldub_code(env, s); 3897 mod = (modrm >> 6) & 3; 3898 ot = gen_pop_T0(s); 3899 if (mod == 3) { 3900 /* NOTE: order is important for pop %sp */ 3901 gen_pop_update(s, ot); 3902 rm = (modrm & 7) | REX_B(s); 3903 gen_op_mov_reg_v(s, ot, rm, s->T0); 3904 } else { 3905 /* NOTE: order is important too for MMU exceptions */ 3906 s->popl_esp_hack = 1 << ot; 3907 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 3908 s->popl_esp_hack = 0; 3909 gen_pop_update(s, ot); 3910 } 3911 break; 3912 case 0xc8: /* enter */ 3913 { 3914 int level; 3915 val = x86_lduw_code(env, s); 3916 level = x86_ldub_code(env, s); 3917 gen_enter(s, val, level); 3918 } 3919 break; 3920 case 0xc9: /* leave */ 3921 gen_leave(s); 3922 break; 3923 case 0x06: /* push es */ 3924 case 0x0e: /* push cs */ 3925 case 0x16: /* push ss */ 3926 case 0x1e: /* push ds */ 3927 if (CODE64(s)) 3928 goto illegal_op; 3929 gen_op_movl_T0_seg(s, b >> 3); 3930 gen_push_v(s, s->T0); 3931 break; 3932 case 0x1a0: /* push fs */ 3933 case 0x1a8: /* push gs */ 3934 gen_op_movl_T0_seg(s, (b >> 3) & 7); 3935 gen_push_v(s, s->T0); 3936 break; 3937 case 0x07: /* pop es */ 3938 case 0x17: /* pop ss */ 3939 case 0x1f: /* pop ds */ 3940 if (CODE64(s)) 3941 goto illegal_op; 3942 reg = b >> 3; 3943 ot = gen_pop_T0(s); 3944 gen_movl_seg_T0(s, reg); 3945 gen_pop_update(s, ot); 3946 break; 3947 case 0x1a1: /* pop fs */ 3948 case 0x1a9: /* pop gs */ 3949 ot = gen_pop_T0(s); 3950 gen_movl_seg_T0(s, (b >> 3) & 7); 3951 gen_pop_update(s, ot); 3952 break; 3953 3954 /**************************/ 3955 /* mov */ 3956 case 0x88: 3957 case 0x89: /* mov Gv, Ev */ 3958 ot = mo_b_d(b, dflag); 3959 modrm = x86_ldub_code(env, s); 3960 reg = ((modrm >> 3) & 7) | REX_R(s); 3961 3962 /* generate a generic store */ 3963 gen_ldst_modrm(env, s, modrm, ot, reg, 1); 3964 break; 3965 case 0xc6: 3966 case 0xc7: /* mov Ev, Iv */ 3967 ot = mo_b_d(b, dflag); 3968 modrm = x86_ldub_code(env, s); 3969 mod = (modrm >> 6) & 3; 3970 if (mod != 3) { 3971 s->rip_offset = insn_const_size(ot); 3972 gen_lea_modrm(env, s, modrm); 3973 } 3974 val = insn_get(env, s, ot); 3975 tcg_gen_movi_tl(s->T0, val); 3976 if (mod != 3) { 3977 gen_op_st_v(s, ot, s->T0, s->A0); 3978 } else { 3979 gen_op_mov_reg_v(s, ot, (modrm & 7) | REX_B(s), s->T0); 3980 } 3981 break; 3982 case 0x8a: 3983 case 0x8b: /* mov Ev, Gv */ 3984 ot = mo_b_d(b, dflag); 3985 modrm = x86_ldub_code(env, s); 3986 reg = ((modrm >> 3) & 7) | REX_R(s); 3987 3988 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3989 gen_op_mov_reg_v(s, ot, reg, s->T0); 3990 break; 3991 case 0x8e: /* mov seg, Gv */ 3992 modrm = x86_ldub_code(env, s); 3993 reg = (modrm >> 3) & 7; 3994 if (reg >= 6 || reg == R_CS) 3995 goto illegal_op; 3996 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 3997 gen_movl_seg_T0(s, reg); 3998 break; 3999 case 0x8c: /* mov Gv, seg */ 4000 modrm = x86_ldub_code(env, s); 4001 reg = (modrm >> 3) & 7; 4002 mod = (modrm >> 6) & 3; 4003 if (reg >= 6) 4004 goto illegal_op; 4005 gen_op_movl_T0_seg(s, reg); 4006 ot = mod == 3 ? dflag : MO_16; 4007 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 4008 break; 4009 4010 case 0x1b6: /* movzbS Gv, Eb */ 4011 case 0x1b7: /* movzwS Gv, Eb */ 4012 case 0x1be: /* movsbS Gv, Eb */ 4013 case 0x1bf: /* movswS Gv, Eb */ 4014 { 4015 MemOp d_ot; 4016 MemOp s_ot; 4017 4018 /* d_ot is the size of destination */ 4019 d_ot = dflag; 4020 /* ot is the size of source */ 4021 ot = (b & 1) + MO_8; 4022 /* s_ot is the sign+size of source */ 4023 s_ot = b & 8 ? MO_SIGN | ot : ot; 4024 4025 modrm = x86_ldub_code(env, s); 4026 reg = ((modrm >> 3) & 7) | REX_R(s); 4027 mod = (modrm >> 6) & 3; 4028 rm = (modrm & 7) | REX_B(s); 4029 4030 if (mod == 3) { 4031 if (s_ot == MO_SB && byte_reg_is_xH(s, rm)) { 4032 tcg_gen_sextract_tl(s->T0, cpu_regs[rm - 4], 8, 8); 4033 } else { 4034 gen_op_mov_v_reg(s, ot, s->T0, rm); 4035 switch (s_ot) { 4036 case MO_UB: 4037 tcg_gen_ext8u_tl(s->T0, s->T0); 4038 break; 4039 case MO_SB: 4040 tcg_gen_ext8s_tl(s->T0, s->T0); 4041 break; 4042 case MO_UW: 4043 tcg_gen_ext16u_tl(s->T0, s->T0); 4044 break; 4045 default: 4046 case MO_SW: 4047 tcg_gen_ext16s_tl(s->T0, s->T0); 4048 break; 4049 } 4050 } 4051 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 4052 } else { 4053 gen_lea_modrm(env, s, modrm); 4054 gen_op_ld_v(s, s_ot, s->T0, s->A0); 4055 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 4056 } 4057 } 4058 break; 4059 4060 case 0x8d: /* lea */ 4061 modrm = x86_ldub_code(env, s); 4062 mod = (modrm >> 6) & 3; 4063 if (mod == 3) 4064 goto illegal_op; 4065 reg = ((modrm >> 3) & 7) | REX_R(s); 4066 { 4067 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4068 TCGv ea = gen_lea_modrm_1(s, a, false); 4069 gen_lea_v_seg(s, s->aflag, ea, -1, -1); 4070 gen_op_mov_reg_v(s, dflag, reg, s->A0); 4071 } 4072 break; 4073 4074 case 0xa0: /* mov EAX, Ov */ 4075 case 0xa1: 4076 case 0xa2: /* mov Ov, EAX */ 4077 case 0xa3: 4078 { 4079 target_ulong offset_addr; 4080 4081 ot = mo_b_d(b, dflag); 4082 offset_addr = insn_get_addr(env, s, s->aflag); 4083 tcg_gen_movi_tl(s->A0, offset_addr); 4084 gen_add_A0_ds_seg(s); 4085 if ((b & 2) == 0) { 4086 gen_op_ld_v(s, ot, s->T0, s->A0); 4087 gen_op_mov_reg_v(s, ot, R_EAX, s->T0); 4088 } else { 4089 gen_op_mov_v_reg(s, ot, s->T0, R_EAX); 4090 gen_op_st_v(s, ot, s->T0, s->A0); 4091 } 4092 } 4093 break; 4094 case 0xd7: /* xlat */ 4095 tcg_gen_mov_tl(s->A0, cpu_regs[R_EBX]); 4096 tcg_gen_ext8u_tl(s->T0, cpu_regs[R_EAX]); 4097 tcg_gen_add_tl(s->A0, s->A0, s->T0); 4098 gen_extu(s->aflag, s->A0); 4099 gen_add_A0_ds_seg(s); 4100 gen_op_ld_v(s, MO_8, s->T0, s->A0); 4101 gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0); 4102 break; 4103 case 0xb0 ... 0xb7: /* mov R, Ib */ 4104 val = insn_get(env, s, MO_8); 4105 tcg_gen_movi_tl(s->T0, val); 4106 gen_op_mov_reg_v(s, MO_8, (b & 7) | REX_B(s), s->T0); 4107 break; 4108 case 0xb8 ... 0xbf: /* mov R, Iv */ 4109 #ifdef TARGET_X86_64 4110 if (dflag == MO_64) { 4111 uint64_t tmp; 4112 /* 64 bit case */ 4113 tmp = x86_ldq_code(env, s); 4114 reg = (b & 7) | REX_B(s); 4115 tcg_gen_movi_tl(s->T0, tmp); 4116 gen_op_mov_reg_v(s, MO_64, reg, s->T0); 4117 } else 4118 #endif 4119 { 4120 ot = dflag; 4121 val = insn_get(env, s, ot); 4122 reg = (b & 7) | REX_B(s); 4123 tcg_gen_movi_tl(s->T0, val); 4124 gen_op_mov_reg_v(s, ot, reg, s->T0); 4125 } 4126 break; 4127 4128 case 0x91 ... 0x97: /* xchg R, EAX */ 4129 do_xchg_reg_eax: 4130 ot = dflag; 4131 reg = (b & 7) | REX_B(s); 4132 rm = R_EAX; 4133 goto do_xchg_reg; 4134 case 0x86: 4135 case 0x87: /* xchg Ev, Gv */ 4136 ot = mo_b_d(b, dflag); 4137 modrm = x86_ldub_code(env, s); 4138 reg = ((modrm >> 3) & 7) | REX_R(s); 4139 mod = (modrm >> 6) & 3; 4140 if (mod == 3) { 4141 rm = (modrm & 7) | REX_B(s); 4142 do_xchg_reg: 4143 gen_op_mov_v_reg(s, ot, s->T0, reg); 4144 gen_op_mov_v_reg(s, ot, s->T1, rm); 4145 gen_op_mov_reg_v(s, ot, rm, s->T0); 4146 gen_op_mov_reg_v(s, ot, reg, s->T1); 4147 } else { 4148 gen_lea_modrm(env, s, modrm); 4149 gen_op_mov_v_reg(s, ot, s->T0, reg); 4150 /* for xchg, lock is implicit */ 4151 tcg_gen_atomic_xchg_tl(s->T1, s->A0, s->T0, 4152 s->mem_index, ot | MO_LE); 4153 gen_op_mov_reg_v(s, ot, reg, s->T1); 4154 } 4155 break; 4156 case 0xc4: /* les Gv */ 4157 /* In CODE64 this is VEX3; see above. */ 4158 op = R_ES; 4159 goto do_lxx; 4160 case 0xc5: /* lds Gv */ 4161 /* In CODE64 this is VEX2; see above. */ 4162 op = R_DS; 4163 goto do_lxx; 4164 case 0x1b2: /* lss Gv */ 4165 op = R_SS; 4166 goto do_lxx; 4167 case 0x1b4: /* lfs Gv */ 4168 op = R_FS; 4169 goto do_lxx; 4170 case 0x1b5: /* lgs Gv */ 4171 op = R_GS; 4172 do_lxx: 4173 ot = dflag != MO_16 ? MO_32 : MO_16; 4174 modrm = x86_ldub_code(env, s); 4175 reg = ((modrm >> 3) & 7) | REX_R(s); 4176 mod = (modrm >> 6) & 3; 4177 if (mod == 3) 4178 goto illegal_op; 4179 gen_lea_modrm(env, s, modrm); 4180 gen_op_ld_v(s, ot, s->T1, s->A0); 4181 gen_add_A0_im(s, 1 << ot); 4182 /* load the segment first to handle exceptions properly */ 4183 gen_op_ld_v(s, MO_16, s->T0, s->A0); 4184 gen_movl_seg_T0(s, op); 4185 /* then put the data */ 4186 gen_op_mov_reg_v(s, ot, reg, s->T1); 4187 break; 4188 4189 /************************/ 4190 /* shifts */ 4191 case 0xc0: 4192 case 0xc1: 4193 /* shift Ev,Ib */ 4194 shift = 2; 4195 grp2: 4196 { 4197 ot = mo_b_d(b, dflag); 4198 modrm = x86_ldub_code(env, s); 4199 mod = (modrm >> 6) & 3; 4200 op = (modrm >> 3) & 7; 4201 4202 if (mod != 3) { 4203 if (shift == 2) { 4204 s->rip_offset = 1; 4205 } 4206 gen_lea_modrm(env, s, modrm); 4207 opreg = OR_TMP0; 4208 } else { 4209 opreg = (modrm & 7) | REX_B(s); 4210 } 4211 4212 /* simpler op */ 4213 if (shift == 0) { 4214 gen_shift(s, op, ot, opreg, OR_ECX); 4215 } else { 4216 if (shift == 2) { 4217 shift = x86_ldub_code(env, s); 4218 } 4219 gen_shifti(s, op, ot, opreg, shift); 4220 } 4221 } 4222 break; 4223 case 0xd0: 4224 case 0xd1: 4225 /* shift Ev,1 */ 4226 shift = 1; 4227 goto grp2; 4228 case 0xd2: 4229 case 0xd3: 4230 /* shift Ev,cl */ 4231 shift = 0; 4232 goto grp2; 4233 4234 case 0x1a4: /* shld imm */ 4235 op = 0; 4236 shift = 1; 4237 goto do_shiftd; 4238 case 0x1a5: /* shld cl */ 4239 op = 0; 4240 shift = 0; 4241 goto do_shiftd; 4242 case 0x1ac: /* shrd imm */ 4243 op = 1; 4244 shift = 1; 4245 goto do_shiftd; 4246 case 0x1ad: /* shrd cl */ 4247 op = 1; 4248 shift = 0; 4249 do_shiftd: 4250 ot = dflag; 4251 modrm = x86_ldub_code(env, s); 4252 mod = (modrm >> 6) & 3; 4253 rm = (modrm & 7) | REX_B(s); 4254 reg = ((modrm >> 3) & 7) | REX_R(s); 4255 if (mod != 3) { 4256 gen_lea_modrm(env, s, modrm); 4257 opreg = OR_TMP0; 4258 } else { 4259 opreg = rm; 4260 } 4261 gen_op_mov_v_reg(s, ot, s->T1, reg); 4262 4263 if (shift) { 4264 TCGv imm = tcg_const_tl(x86_ldub_code(env, s)); 4265 gen_shiftd_rm_T1(s, ot, opreg, op, imm); 4266 tcg_temp_free(imm); 4267 } else { 4268 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]); 4269 } 4270 break; 4271 4272 /************************/ 4273 /* floats */ 4274 case 0xd8 ... 0xdf: 4275 { 4276 bool update_fip = true; 4277 4278 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 4279 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 4280 /* XXX: what to do if illegal op ? */ 4281 gen_exception(s, EXCP07_PREX); 4282 break; 4283 } 4284 modrm = x86_ldub_code(env, s); 4285 mod = (modrm >> 6) & 3; 4286 rm = modrm & 7; 4287 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 4288 if (mod != 3) { 4289 /* memory op */ 4290 AddressParts a = gen_lea_modrm_0(env, s, modrm); 4291 TCGv ea = gen_lea_modrm_1(s, a, false); 4292 TCGv last_addr = tcg_temp_new(); 4293 bool update_fdp = true; 4294 4295 tcg_gen_mov_tl(last_addr, ea); 4296 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override); 4297 4298 switch (op) { 4299 case 0x00 ... 0x07: /* fxxxs */ 4300 case 0x10 ... 0x17: /* fixxxl */ 4301 case 0x20 ... 0x27: /* fxxxl */ 4302 case 0x30 ... 0x37: /* fixxx */ 4303 { 4304 int op1; 4305 op1 = op & 7; 4306 4307 switch (op >> 4) { 4308 case 0: 4309 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4310 s->mem_index, MO_LEUL); 4311 gen_helper_flds_FT0(cpu_env, s->tmp2_i32); 4312 break; 4313 case 1: 4314 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4315 s->mem_index, MO_LEUL); 4316 gen_helper_fildl_FT0(cpu_env, s->tmp2_i32); 4317 break; 4318 case 2: 4319 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 4320 s->mem_index, MO_LEUQ); 4321 gen_helper_fldl_FT0(cpu_env, s->tmp1_i64); 4322 break; 4323 case 3: 4324 default: 4325 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4326 s->mem_index, MO_LESW); 4327 gen_helper_fildl_FT0(cpu_env, s->tmp2_i32); 4328 break; 4329 } 4330 4331 gen_helper_fp_arith_ST0_FT0(op1); 4332 if (op1 == 3) { 4333 /* fcomp needs pop */ 4334 gen_helper_fpop(cpu_env); 4335 } 4336 } 4337 break; 4338 case 0x08: /* flds */ 4339 case 0x0a: /* fsts */ 4340 case 0x0b: /* fstps */ 4341 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 4342 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 4343 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 4344 switch (op & 7) { 4345 case 0: 4346 switch (op >> 4) { 4347 case 0: 4348 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4349 s->mem_index, MO_LEUL); 4350 gen_helper_flds_ST0(cpu_env, s->tmp2_i32); 4351 break; 4352 case 1: 4353 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4354 s->mem_index, MO_LEUL); 4355 gen_helper_fildl_ST0(cpu_env, s->tmp2_i32); 4356 break; 4357 case 2: 4358 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 4359 s->mem_index, MO_LEUQ); 4360 gen_helper_fldl_ST0(cpu_env, s->tmp1_i64); 4361 break; 4362 case 3: 4363 default: 4364 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4365 s->mem_index, MO_LESW); 4366 gen_helper_fildl_ST0(cpu_env, s->tmp2_i32); 4367 break; 4368 } 4369 break; 4370 case 1: 4371 /* XXX: the corresponding CPUID bit must be tested ! */ 4372 switch (op >> 4) { 4373 case 1: 4374 gen_helper_fisttl_ST0(s->tmp2_i32, cpu_env); 4375 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4376 s->mem_index, MO_LEUL); 4377 break; 4378 case 2: 4379 gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env); 4380 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 4381 s->mem_index, MO_LEUQ); 4382 break; 4383 case 3: 4384 default: 4385 gen_helper_fistt_ST0(s->tmp2_i32, cpu_env); 4386 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4387 s->mem_index, MO_LEUW); 4388 break; 4389 } 4390 gen_helper_fpop(cpu_env); 4391 break; 4392 default: 4393 switch (op >> 4) { 4394 case 0: 4395 gen_helper_fsts_ST0(s->tmp2_i32, cpu_env); 4396 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4397 s->mem_index, MO_LEUL); 4398 break; 4399 case 1: 4400 gen_helper_fistl_ST0(s->tmp2_i32, cpu_env); 4401 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4402 s->mem_index, MO_LEUL); 4403 break; 4404 case 2: 4405 gen_helper_fstl_ST0(s->tmp1_i64, cpu_env); 4406 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 4407 s->mem_index, MO_LEUQ); 4408 break; 4409 case 3: 4410 default: 4411 gen_helper_fist_ST0(s->tmp2_i32, cpu_env); 4412 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4413 s->mem_index, MO_LEUW); 4414 break; 4415 } 4416 if ((op & 7) == 3) { 4417 gen_helper_fpop(cpu_env); 4418 } 4419 break; 4420 } 4421 break; 4422 case 0x0c: /* fldenv mem */ 4423 gen_helper_fldenv(cpu_env, s->A0, 4424 tcg_const_i32(dflag - 1)); 4425 update_fip = update_fdp = false; 4426 break; 4427 case 0x0d: /* fldcw mem */ 4428 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 4429 s->mem_index, MO_LEUW); 4430 gen_helper_fldcw(cpu_env, s->tmp2_i32); 4431 update_fip = update_fdp = false; 4432 break; 4433 case 0x0e: /* fnstenv mem */ 4434 gen_helper_fstenv(cpu_env, s->A0, 4435 tcg_const_i32(dflag - 1)); 4436 update_fip = update_fdp = false; 4437 break; 4438 case 0x0f: /* fnstcw mem */ 4439 gen_helper_fnstcw(s->tmp2_i32, cpu_env); 4440 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4441 s->mem_index, MO_LEUW); 4442 update_fip = update_fdp = false; 4443 break; 4444 case 0x1d: /* fldt mem */ 4445 gen_helper_fldt_ST0(cpu_env, s->A0); 4446 break; 4447 case 0x1f: /* fstpt mem */ 4448 gen_helper_fstt_ST0(cpu_env, s->A0); 4449 gen_helper_fpop(cpu_env); 4450 break; 4451 case 0x2c: /* frstor mem */ 4452 gen_helper_frstor(cpu_env, s->A0, 4453 tcg_const_i32(dflag - 1)); 4454 update_fip = update_fdp = false; 4455 break; 4456 case 0x2e: /* fnsave mem */ 4457 gen_helper_fsave(cpu_env, s->A0, 4458 tcg_const_i32(dflag - 1)); 4459 update_fip = update_fdp = false; 4460 break; 4461 case 0x2f: /* fnstsw mem */ 4462 gen_helper_fnstsw(s->tmp2_i32, cpu_env); 4463 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 4464 s->mem_index, MO_LEUW); 4465 update_fip = update_fdp = false; 4466 break; 4467 case 0x3c: /* fbld */ 4468 gen_helper_fbld_ST0(cpu_env, s->A0); 4469 break; 4470 case 0x3e: /* fbstp */ 4471 gen_helper_fbst_ST0(cpu_env, s->A0); 4472 gen_helper_fpop(cpu_env); 4473 break; 4474 case 0x3d: /* fildll */ 4475 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 4476 s->mem_index, MO_LEUQ); 4477 gen_helper_fildll_ST0(cpu_env, s->tmp1_i64); 4478 break; 4479 case 0x3f: /* fistpll */ 4480 gen_helper_fistll_ST0(s->tmp1_i64, cpu_env); 4481 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 4482 s->mem_index, MO_LEUQ); 4483 gen_helper_fpop(cpu_env); 4484 break; 4485 default: 4486 goto unknown_op; 4487 } 4488 4489 if (update_fdp) { 4490 int last_seg = s->override >= 0 ? s->override : a.def_seg; 4491 4492 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, 4493 offsetof(CPUX86State, 4494 segs[last_seg].selector)); 4495 tcg_gen_st16_i32(s->tmp2_i32, cpu_env, 4496 offsetof(CPUX86State, fpds)); 4497 tcg_gen_st_tl(last_addr, cpu_env, 4498 offsetof(CPUX86State, fpdp)); 4499 } 4500 tcg_temp_free(last_addr); 4501 } else { 4502 /* register float ops */ 4503 opreg = rm; 4504 4505 switch (op) { 4506 case 0x08: /* fld sti */ 4507 gen_helper_fpush(cpu_env); 4508 gen_helper_fmov_ST0_STN(cpu_env, 4509 tcg_const_i32((opreg + 1) & 7)); 4510 break; 4511 case 0x09: /* fxchg sti */ 4512 case 0x29: /* fxchg4 sti, undocumented op */ 4513 case 0x39: /* fxchg7 sti, undocumented op */ 4514 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg)); 4515 break; 4516 case 0x0a: /* grp d9/2 */ 4517 switch (rm) { 4518 case 0: /* fnop */ 4519 /* check exceptions (FreeBSD FPU probe) */ 4520 gen_helper_fwait(cpu_env); 4521 update_fip = false; 4522 break; 4523 default: 4524 goto unknown_op; 4525 } 4526 break; 4527 case 0x0c: /* grp d9/4 */ 4528 switch (rm) { 4529 case 0: /* fchs */ 4530 gen_helper_fchs_ST0(cpu_env); 4531 break; 4532 case 1: /* fabs */ 4533 gen_helper_fabs_ST0(cpu_env); 4534 break; 4535 case 4: /* ftst */ 4536 gen_helper_fldz_FT0(cpu_env); 4537 gen_helper_fcom_ST0_FT0(cpu_env); 4538 break; 4539 case 5: /* fxam */ 4540 gen_helper_fxam_ST0(cpu_env); 4541 break; 4542 default: 4543 goto unknown_op; 4544 } 4545 break; 4546 case 0x0d: /* grp d9/5 */ 4547 { 4548 switch (rm) { 4549 case 0: 4550 gen_helper_fpush(cpu_env); 4551 gen_helper_fld1_ST0(cpu_env); 4552 break; 4553 case 1: 4554 gen_helper_fpush(cpu_env); 4555 gen_helper_fldl2t_ST0(cpu_env); 4556 break; 4557 case 2: 4558 gen_helper_fpush(cpu_env); 4559 gen_helper_fldl2e_ST0(cpu_env); 4560 break; 4561 case 3: 4562 gen_helper_fpush(cpu_env); 4563 gen_helper_fldpi_ST0(cpu_env); 4564 break; 4565 case 4: 4566 gen_helper_fpush(cpu_env); 4567 gen_helper_fldlg2_ST0(cpu_env); 4568 break; 4569 case 5: 4570 gen_helper_fpush(cpu_env); 4571 gen_helper_fldln2_ST0(cpu_env); 4572 break; 4573 case 6: 4574 gen_helper_fpush(cpu_env); 4575 gen_helper_fldz_ST0(cpu_env); 4576 break; 4577 default: 4578 goto unknown_op; 4579 } 4580 } 4581 break; 4582 case 0x0e: /* grp d9/6 */ 4583 switch (rm) { 4584 case 0: /* f2xm1 */ 4585 gen_helper_f2xm1(cpu_env); 4586 break; 4587 case 1: /* fyl2x */ 4588 gen_helper_fyl2x(cpu_env); 4589 break; 4590 case 2: /* fptan */ 4591 gen_helper_fptan(cpu_env); 4592 break; 4593 case 3: /* fpatan */ 4594 gen_helper_fpatan(cpu_env); 4595 break; 4596 case 4: /* fxtract */ 4597 gen_helper_fxtract(cpu_env); 4598 break; 4599 case 5: /* fprem1 */ 4600 gen_helper_fprem1(cpu_env); 4601 break; 4602 case 6: /* fdecstp */ 4603 gen_helper_fdecstp(cpu_env); 4604 break; 4605 default: 4606 case 7: /* fincstp */ 4607 gen_helper_fincstp(cpu_env); 4608 break; 4609 } 4610 break; 4611 case 0x0f: /* grp d9/7 */ 4612 switch (rm) { 4613 case 0: /* fprem */ 4614 gen_helper_fprem(cpu_env); 4615 break; 4616 case 1: /* fyl2xp1 */ 4617 gen_helper_fyl2xp1(cpu_env); 4618 break; 4619 case 2: /* fsqrt */ 4620 gen_helper_fsqrt(cpu_env); 4621 break; 4622 case 3: /* fsincos */ 4623 gen_helper_fsincos(cpu_env); 4624 break; 4625 case 5: /* fscale */ 4626 gen_helper_fscale(cpu_env); 4627 break; 4628 case 4: /* frndint */ 4629 gen_helper_frndint(cpu_env); 4630 break; 4631 case 6: /* fsin */ 4632 gen_helper_fsin(cpu_env); 4633 break; 4634 default: 4635 case 7: /* fcos */ 4636 gen_helper_fcos(cpu_env); 4637 break; 4638 } 4639 break; 4640 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 4641 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 4642 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 4643 { 4644 int op1; 4645 4646 op1 = op & 7; 4647 if (op >= 0x20) { 4648 gen_helper_fp_arith_STN_ST0(op1, opreg); 4649 if (op >= 0x30) { 4650 gen_helper_fpop(cpu_env); 4651 } 4652 } else { 4653 gen_helper_fmov_FT0_STN(cpu_env, 4654 tcg_const_i32(opreg)); 4655 gen_helper_fp_arith_ST0_FT0(op1); 4656 } 4657 } 4658 break; 4659 case 0x02: /* fcom */ 4660 case 0x22: /* fcom2, undocumented op */ 4661 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4662 gen_helper_fcom_ST0_FT0(cpu_env); 4663 break; 4664 case 0x03: /* fcomp */ 4665 case 0x23: /* fcomp3, undocumented op */ 4666 case 0x32: /* fcomp5, undocumented op */ 4667 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4668 gen_helper_fcom_ST0_FT0(cpu_env); 4669 gen_helper_fpop(cpu_env); 4670 break; 4671 case 0x15: /* da/5 */ 4672 switch (rm) { 4673 case 1: /* fucompp */ 4674 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1)); 4675 gen_helper_fucom_ST0_FT0(cpu_env); 4676 gen_helper_fpop(cpu_env); 4677 gen_helper_fpop(cpu_env); 4678 break; 4679 default: 4680 goto unknown_op; 4681 } 4682 break; 4683 case 0x1c: 4684 switch (rm) { 4685 case 0: /* feni (287 only, just do nop here) */ 4686 break; 4687 case 1: /* fdisi (287 only, just do nop here) */ 4688 break; 4689 case 2: /* fclex */ 4690 gen_helper_fclex(cpu_env); 4691 update_fip = false; 4692 break; 4693 case 3: /* fninit */ 4694 gen_helper_fninit(cpu_env); 4695 update_fip = false; 4696 break; 4697 case 4: /* fsetpm (287 only, just do nop here) */ 4698 break; 4699 default: 4700 goto unknown_op; 4701 } 4702 break; 4703 case 0x1d: /* fucomi */ 4704 if (!(s->cpuid_features & CPUID_CMOV)) { 4705 goto illegal_op; 4706 } 4707 gen_update_cc_op(s); 4708 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4709 gen_helper_fucomi_ST0_FT0(cpu_env); 4710 set_cc_op(s, CC_OP_EFLAGS); 4711 break; 4712 case 0x1e: /* fcomi */ 4713 if (!(s->cpuid_features & CPUID_CMOV)) { 4714 goto illegal_op; 4715 } 4716 gen_update_cc_op(s); 4717 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4718 gen_helper_fcomi_ST0_FT0(cpu_env); 4719 set_cc_op(s, CC_OP_EFLAGS); 4720 break; 4721 case 0x28: /* ffree sti */ 4722 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg)); 4723 break; 4724 case 0x2a: /* fst sti */ 4725 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg)); 4726 break; 4727 case 0x2b: /* fstp sti */ 4728 case 0x0b: /* fstp1 sti, undocumented op */ 4729 case 0x3a: /* fstp8 sti, undocumented op */ 4730 case 0x3b: /* fstp9 sti, undocumented op */ 4731 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg)); 4732 gen_helper_fpop(cpu_env); 4733 break; 4734 case 0x2c: /* fucom st(i) */ 4735 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4736 gen_helper_fucom_ST0_FT0(cpu_env); 4737 break; 4738 case 0x2d: /* fucomp st(i) */ 4739 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4740 gen_helper_fucom_ST0_FT0(cpu_env); 4741 gen_helper_fpop(cpu_env); 4742 break; 4743 case 0x33: /* de/3 */ 4744 switch (rm) { 4745 case 1: /* fcompp */ 4746 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1)); 4747 gen_helper_fcom_ST0_FT0(cpu_env); 4748 gen_helper_fpop(cpu_env); 4749 gen_helper_fpop(cpu_env); 4750 break; 4751 default: 4752 goto unknown_op; 4753 } 4754 break; 4755 case 0x38: /* ffreep sti, undocumented op */ 4756 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg)); 4757 gen_helper_fpop(cpu_env); 4758 break; 4759 case 0x3c: /* df/4 */ 4760 switch (rm) { 4761 case 0: 4762 gen_helper_fnstsw(s->tmp2_i32, cpu_env); 4763 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 4764 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 4765 break; 4766 default: 4767 goto unknown_op; 4768 } 4769 break; 4770 case 0x3d: /* fucomip */ 4771 if (!(s->cpuid_features & CPUID_CMOV)) { 4772 goto illegal_op; 4773 } 4774 gen_update_cc_op(s); 4775 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4776 gen_helper_fucomi_ST0_FT0(cpu_env); 4777 gen_helper_fpop(cpu_env); 4778 set_cc_op(s, CC_OP_EFLAGS); 4779 break; 4780 case 0x3e: /* fcomip */ 4781 if (!(s->cpuid_features & CPUID_CMOV)) { 4782 goto illegal_op; 4783 } 4784 gen_update_cc_op(s); 4785 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 4786 gen_helper_fcomi_ST0_FT0(cpu_env); 4787 gen_helper_fpop(cpu_env); 4788 set_cc_op(s, CC_OP_EFLAGS); 4789 break; 4790 case 0x10 ... 0x13: /* fcmovxx */ 4791 case 0x18 ... 0x1b: 4792 { 4793 int op1; 4794 TCGLabel *l1; 4795 static const uint8_t fcmov_cc[8] = { 4796 (JCC_B << 1), 4797 (JCC_Z << 1), 4798 (JCC_BE << 1), 4799 (JCC_P << 1), 4800 }; 4801 4802 if (!(s->cpuid_features & CPUID_CMOV)) { 4803 goto illegal_op; 4804 } 4805 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 4806 l1 = gen_new_label(); 4807 gen_jcc1_noeob(s, op1, l1); 4808 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg)); 4809 gen_set_label(l1); 4810 } 4811 break; 4812 default: 4813 goto unknown_op; 4814 } 4815 } 4816 4817 if (update_fip) { 4818 tcg_gen_ld_i32(s->tmp2_i32, cpu_env, 4819 offsetof(CPUX86State, segs[R_CS].selector)); 4820 tcg_gen_st16_i32(s->tmp2_i32, cpu_env, 4821 offsetof(CPUX86State, fpcs)); 4822 tcg_gen_st_tl(eip_cur_tl(s), 4823 cpu_env, offsetof(CPUX86State, fpip)); 4824 } 4825 } 4826 break; 4827 /************************/ 4828 /* string ops */ 4829 4830 case 0xa4: /* movsS */ 4831 case 0xa5: 4832 ot = mo_b_d(b, dflag); 4833 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4834 gen_repz_movs(s, ot); 4835 } else { 4836 gen_movs(s, ot); 4837 } 4838 break; 4839 4840 case 0xaa: /* stosS */ 4841 case 0xab: 4842 ot = mo_b_d(b, dflag); 4843 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4844 gen_repz_stos(s, ot); 4845 } else { 4846 gen_stos(s, ot); 4847 } 4848 break; 4849 case 0xac: /* lodsS */ 4850 case 0xad: 4851 ot = mo_b_d(b, dflag); 4852 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4853 gen_repz_lods(s, ot); 4854 } else { 4855 gen_lods(s, ot); 4856 } 4857 break; 4858 case 0xae: /* scasS */ 4859 case 0xaf: 4860 ot = mo_b_d(b, dflag); 4861 if (prefixes & PREFIX_REPNZ) { 4862 gen_repz_scas(s, ot, 1); 4863 } else if (prefixes & PREFIX_REPZ) { 4864 gen_repz_scas(s, ot, 0); 4865 } else { 4866 gen_scas(s, ot); 4867 } 4868 break; 4869 4870 case 0xa6: /* cmpsS */ 4871 case 0xa7: 4872 ot = mo_b_d(b, dflag); 4873 if (prefixes & PREFIX_REPNZ) { 4874 gen_repz_cmps(s, ot, 1); 4875 } else if (prefixes & PREFIX_REPZ) { 4876 gen_repz_cmps(s, ot, 0); 4877 } else { 4878 gen_cmps(s, ot); 4879 } 4880 break; 4881 case 0x6c: /* insS */ 4882 case 0x6d: 4883 ot = mo_b_d32(b, dflag); 4884 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 4885 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 4886 if (!gen_check_io(s, ot, s->tmp2_i32, 4887 SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) { 4888 break; 4889 } 4890 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4891 gen_io_start(); 4892 s->base.is_jmp = DISAS_TOO_MANY; 4893 } 4894 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4895 gen_repz_ins(s, ot); 4896 } else { 4897 gen_ins(s, ot); 4898 } 4899 break; 4900 case 0x6e: /* outsS */ 4901 case 0x6f: 4902 ot = mo_b_d32(b, dflag); 4903 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 4904 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 4905 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) { 4906 break; 4907 } 4908 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4909 gen_io_start(); 4910 s->base.is_jmp = DISAS_TOO_MANY; 4911 } 4912 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 4913 gen_repz_outs(s, ot); 4914 } else { 4915 gen_outs(s, ot); 4916 } 4917 break; 4918 4919 /************************/ 4920 /* port I/O */ 4921 4922 case 0xe4: 4923 case 0xe5: 4924 ot = mo_b_d32(b, dflag); 4925 val = x86_ldub_code(env, s); 4926 tcg_gen_movi_i32(s->tmp2_i32, val); 4927 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) { 4928 break; 4929 } 4930 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4931 gen_io_start(); 4932 s->base.is_jmp = DISAS_TOO_MANY; 4933 } 4934 gen_helper_in_func(ot, s->T1, s->tmp2_i32); 4935 gen_op_mov_reg_v(s, ot, R_EAX, s->T1); 4936 gen_bpt_io(s, s->tmp2_i32, ot); 4937 break; 4938 case 0xe6: 4939 case 0xe7: 4940 ot = mo_b_d32(b, dflag); 4941 val = x86_ldub_code(env, s); 4942 tcg_gen_movi_i32(s->tmp2_i32, val); 4943 if (!gen_check_io(s, ot, s->tmp2_i32, 0)) { 4944 break; 4945 } 4946 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4947 gen_io_start(); 4948 s->base.is_jmp = DISAS_TOO_MANY; 4949 } 4950 gen_op_mov_v_reg(s, ot, s->T1, R_EAX); 4951 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 4952 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 4953 gen_bpt_io(s, s->tmp2_i32, ot); 4954 break; 4955 case 0xec: 4956 case 0xed: 4957 ot = mo_b_d32(b, dflag); 4958 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 4959 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 4960 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) { 4961 break; 4962 } 4963 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4964 gen_io_start(); 4965 s->base.is_jmp = DISAS_TOO_MANY; 4966 } 4967 gen_helper_in_func(ot, s->T1, s->tmp2_i32); 4968 gen_op_mov_reg_v(s, ot, R_EAX, s->T1); 4969 gen_bpt_io(s, s->tmp2_i32, ot); 4970 break; 4971 case 0xee: 4972 case 0xef: 4973 ot = mo_b_d32(b, dflag); 4974 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 4975 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32); 4976 if (!gen_check_io(s, ot, s->tmp2_i32, 0)) { 4977 break; 4978 } 4979 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 4980 gen_io_start(); 4981 s->base.is_jmp = DISAS_TOO_MANY; 4982 } 4983 gen_op_mov_v_reg(s, ot, s->T1, R_EAX); 4984 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); 4985 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 4986 gen_bpt_io(s, s->tmp2_i32, ot); 4987 break; 4988 4989 /************************/ 4990 /* control */ 4991 case 0xc2: /* ret im */ 4992 val = x86_ldsw_code(env, s); 4993 ot = gen_pop_T0(s); 4994 gen_stack_update(s, val + (1 << ot)); 4995 /* Note that gen_pop_T0 uses a zero-extending load. */ 4996 gen_op_jmp_v(s, s->T0); 4997 gen_bnd_jmp(s); 4998 s->base.is_jmp = DISAS_JUMP; 4999 break; 5000 case 0xc3: /* ret */ 5001 ot = gen_pop_T0(s); 5002 gen_pop_update(s, ot); 5003 /* Note that gen_pop_T0 uses a zero-extending load. */ 5004 gen_op_jmp_v(s, s->T0); 5005 gen_bnd_jmp(s); 5006 s->base.is_jmp = DISAS_JUMP; 5007 break; 5008 case 0xca: /* lret im */ 5009 val = x86_ldsw_code(env, s); 5010 do_lret: 5011 if (PE(s) && !VM86(s)) { 5012 gen_update_cc_op(s); 5013 gen_update_eip_cur(s); 5014 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1), 5015 tcg_const_i32(val)); 5016 } else { 5017 gen_stack_A0(s); 5018 /* pop offset */ 5019 gen_op_ld_v(s, dflag, s->T0, s->A0); 5020 /* NOTE: keeping EIP updated is not a problem in case of 5021 exception */ 5022 gen_op_jmp_v(s, s->T0); 5023 /* pop selector */ 5024 gen_add_A0_im(s, 1 << dflag); 5025 gen_op_ld_v(s, dflag, s->T0, s->A0); 5026 gen_op_movl_seg_T0_vm(s, R_CS); 5027 /* add stack offset */ 5028 gen_stack_update(s, val + (2 << dflag)); 5029 } 5030 s->base.is_jmp = DISAS_EOB_ONLY; 5031 break; 5032 case 0xcb: /* lret */ 5033 val = 0; 5034 goto do_lret; 5035 case 0xcf: /* iret */ 5036 gen_svm_check_intercept(s, SVM_EXIT_IRET); 5037 if (!PE(s) || VM86(s)) { 5038 /* real mode or vm86 mode */ 5039 if (!check_vm86_iopl(s)) { 5040 break; 5041 } 5042 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1)); 5043 } else { 5044 gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1), 5045 eip_next_i32(s)); 5046 } 5047 set_cc_op(s, CC_OP_EFLAGS); 5048 s->base.is_jmp = DISAS_EOB_ONLY; 5049 break; 5050 case 0xe8: /* call im */ 5051 { 5052 int diff = (dflag != MO_16 5053 ? (int32_t)insn_get(env, s, MO_32) 5054 : (int16_t)insn_get(env, s, MO_16)); 5055 gen_push_v(s, eip_next_tl(s)); 5056 gen_bnd_jmp(s); 5057 gen_jmp_rel(s, dflag, diff, 0); 5058 } 5059 break; 5060 case 0x9a: /* lcall im */ 5061 { 5062 unsigned int selector, offset; 5063 5064 if (CODE64(s)) 5065 goto illegal_op; 5066 ot = dflag; 5067 offset = insn_get(env, s, ot); 5068 selector = insn_get(env, s, MO_16); 5069 5070 tcg_gen_movi_tl(s->T0, selector); 5071 tcg_gen_movi_tl(s->T1, offset); 5072 } 5073 goto do_lcall; 5074 case 0xe9: /* jmp im */ 5075 { 5076 int diff = (dflag != MO_16 5077 ? (int32_t)insn_get(env, s, MO_32) 5078 : (int16_t)insn_get(env, s, MO_16)); 5079 gen_bnd_jmp(s); 5080 gen_jmp_rel(s, dflag, diff, 0); 5081 } 5082 break; 5083 case 0xea: /* ljmp im */ 5084 { 5085 unsigned int selector, offset; 5086 5087 if (CODE64(s)) 5088 goto illegal_op; 5089 ot = dflag; 5090 offset = insn_get(env, s, ot); 5091 selector = insn_get(env, s, MO_16); 5092 5093 tcg_gen_movi_tl(s->T0, selector); 5094 tcg_gen_movi_tl(s->T1, offset); 5095 } 5096 goto do_ljmp; 5097 case 0xeb: /* jmp Jb */ 5098 { 5099 int diff = (int8_t)insn_get(env, s, MO_8); 5100 gen_jmp_rel(s, dflag, diff, 0); 5101 } 5102 break; 5103 case 0x70 ... 0x7f: /* jcc Jb */ 5104 { 5105 int diff = (int8_t)insn_get(env, s, MO_8); 5106 gen_bnd_jmp(s); 5107 gen_jcc(s, b, diff); 5108 } 5109 break; 5110 case 0x180 ... 0x18f: /* jcc Jv */ 5111 { 5112 int diff = (dflag != MO_16 5113 ? (int32_t)insn_get(env, s, MO_32) 5114 : (int16_t)insn_get(env, s, MO_16)); 5115 gen_bnd_jmp(s); 5116 gen_jcc(s, b, diff); 5117 } 5118 break; 5119 5120 case 0x190 ... 0x19f: /* setcc Gv */ 5121 modrm = x86_ldub_code(env, s); 5122 gen_setcc1(s, b, s->T0); 5123 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1); 5124 break; 5125 case 0x140 ... 0x14f: /* cmov Gv, Ev */ 5126 if (!(s->cpuid_features & CPUID_CMOV)) { 5127 goto illegal_op; 5128 } 5129 ot = dflag; 5130 modrm = x86_ldub_code(env, s); 5131 reg = ((modrm >> 3) & 7) | REX_R(s); 5132 gen_cmovcc1(env, s, ot, b, modrm, reg); 5133 break; 5134 5135 /************************/ 5136 /* flags */ 5137 case 0x9c: /* pushf */ 5138 gen_svm_check_intercept(s, SVM_EXIT_PUSHF); 5139 if (check_vm86_iopl(s)) { 5140 gen_update_cc_op(s); 5141 gen_helper_read_eflags(s->T0, cpu_env); 5142 gen_push_v(s, s->T0); 5143 } 5144 break; 5145 case 0x9d: /* popf */ 5146 gen_svm_check_intercept(s, SVM_EXIT_POPF); 5147 if (check_vm86_iopl(s)) { 5148 ot = gen_pop_T0(s); 5149 if (CPL(s) == 0) { 5150 if (dflag != MO_16) { 5151 gen_helper_write_eflags(cpu_env, s->T0, 5152 tcg_const_i32((TF_MASK | AC_MASK | 5153 ID_MASK | NT_MASK | 5154 IF_MASK | 5155 IOPL_MASK))); 5156 } else { 5157 gen_helper_write_eflags(cpu_env, s->T0, 5158 tcg_const_i32((TF_MASK | AC_MASK | 5159 ID_MASK | NT_MASK | 5160 IF_MASK | IOPL_MASK) 5161 & 0xffff)); 5162 } 5163 } else { 5164 if (CPL(s) <= IOPL(s)) { 5165 if (dflag != MO_16) { 5166 gen_helper_write_eflags(cpu_env, s->T0, 5167 tcg_const_i32((TF_MASK | 5168 AC_MASK | 5169 ID_MASK | 5170 NT_MASK | 5171 IF_MASK))); 5172 } else { 5173 gen_helper_write_eflags(cpu_env, s->T0, 5174 tcg_const_i32((TF_MASK | 5175 AC_MASK | 5176 ID_MASK | 5177 NT_MASK | 5178 IF_MASK) 5179 & 0xffff)); 5180 } 5181 } else { 5182 if (dflag != MO_16) { 5183 gen_helper_write_eflags(cpu_env, s->T0, 5184 tcg_const_i32((TF_MASK | AC_MASK | 5185 ID_MASK | NT_MASK))); 5186 } else { 5187 gen_helper_write_eflags(cpu_env, s->T0, 5188 tcg_const_i32((TF_MASK | AC_MASK | 5189 ID_MASK | NT_MASK) 5190 & 0xffff)); 5191 } 5192 } 5193 } 5194 gen_pop_update(s, ot); 5195 set_cc_op(s, CC_OP_EFLAGS); 5196 /* abort translation because TF/AC flag may change */ 5197 s->base.is_jmp = DISAS_EOB_NEXT; 5198 } 5199 break; 5200 case 0x9e: /* sahf */ 5201 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) 5202 goto illegal_op; 5203 gen_op_mov_v_reg(s, MO_8, s->T0, R_AH); 5204 gen_compute_eflags(s); 5205 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O); 5206 tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C); 5207 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0); 5208 break; 5209 case 0x9f: /* lahf */ 5210 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) 5211 goto illegal_op; 5212 gen_compute_eflags(s); 5213 /* Note: gen_compute_eflags() only gives the condition codes */ 5214 tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02); 5215 gen_op_mov_reg_v(s, MO_8, R_AH, s->T0); 5216 break; 5217 case 0xf5: /* cmc */ 5218 gen_compute_eflags(s); 5219 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C); 5220 break; 5221 case 0xf8: /* clc */ 5222 gen_compute_eflags(s); 5223 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C); 5224 break; 5225 case 0xf9: /* stc */ 5226 gen_compute_eflags(s); 5227 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C); 5228 break; 5229 case 0xfc: /* cld */ 5230 tcg_gen_movi_i32(s->tmp2_i32, 1); 5231 tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df)); 5232 break; 5233 case 0xfd: /* std */ 5234 tcg_gen_movi_i32(s->tmp2_i32, -1); 5235 tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df)); 5236 break; 5237 5238 /************************/ 5239 /* bit operations */ 5240 case 0x1ba: /* bt/bts/btr/btc Gv, im */ 5241 ot = dflag; 5242 modrm = x86_ldub_code(env, s); 5243 op = (modrm >> 3) & 7; 5244 mod = (modrm >> 6) & 3; 5245 rm = (modrm & 7) | REX_B(s); 5246 if (mod != 3) { 5247 s->rip_offset = 1; 5248 gen_lea_modrm(env, s, modrm); 5249 if (!(s->prefix & PREFIX_LOCK)) { 5250 gen_op_ld_v(s, ot, s->T0, s->A0); 5251 } 5252 } else { 5253 gen_op_mov_v_reg(s, ot, s->T0, rm); 5254 } 5255 /* load shift */ 5256 val = x86_ldub_code(env, s); 5257 tcg_gen_movi_tl(s->T1, val); 5258 if (op < 4) 5259 goto unknown_op; 5260 op -= 4; 5261 goto bt_op; 5262 case 0x1a3: /* bt Gv, Ev */ 5263 op = 0; 5264 goto do_btx; 5265 case 0x1ab: /* bts */ 5266 op = 1; 5267 goto do_btx; 5268 case 0x1b3: /* btr */ 5269 op = 2; 5270 goto do_btx; 5271 case 0x1bb: /* btc */ 5272 op = 3; 5273 do_btx: 5274 ot = dflag; 5275 modrm = x86_ldub_code(env, s); 5276 reg = ((modrm >> 3) & 7) | REX_R(s); 5277 mod = (modrm >> 6) & 3; 5278 rm = (modrm & 7) | REX_B(s); 5279 gen_op_mov_v_reg(s, MO_32, s->T1, reg); 5280 if (mod != 3) { 5281 AddressParts a = gen_lea_modrm_0(env, s, modrm); 5282 /* specific case: we need to add a displacement */ 5283 gen_exts(ot, s->T1); 5284 tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot); 5285 tcg_gen_shli_tl(s->tmp0, s->tmp0, ot); 5286 tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0); 5287 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 5288 if (!(s->prefix & PREFIX_LOCK)) { 5289 gen_op_ld_v(s, ot, s->T0, s->A0); 5290 } 5291 } else { 5292 gen_op_mov_v_reg(s, ot, s->T0, rm); 5293 } 5294 bt_op: 5295 tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1); 5296 tcg_gen_movi_tl(s->tmp0, 1); 5297 tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1); 5298 if (s->prefix & PREFIX_LOCK) { 5299 switch (op) { 5300 case 0: /* bt */ 5301 /* Needs no atomic ops; we surpressed the normal 5302 memory load for LOCK above so do it now. */ 5303 gen_op_ld_v(s, ot, s->T0, s->A0); 5304 break; 5305 case 1: /* bts */ 5306 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0, 5307 s->mem_index, ot | MO_LE); 5308 break; 5309 case 2: /* btr */ 5310 tcg_gen_not_tl(s->tmp0, s->tmp0); 5311 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0, 5312 s->mem_index, ot | MO_LE); 5313 break; 5314 default: 5315 case 3: /* btc */ 5316 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0, 5317 s->mem_index, ot | MO_LE); 5318 break; 5319 } 5320 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 5321 } else { 5322 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 5323 switch (op) { 5324 case 0: /* bt */ 5325 /* Data already loaded; nothing to do. */ 5326 break; 5327 case 1: /* bts */ 5328 tcg_gen_or_tl(s->T0, s->T0, s->tmp0); 5329 break; 5330 case 2: /* btr */ 5331 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0); 5332 break; 5333 default: 5334 case 3: /* btc */ 5335 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0); 5336 break; 5337 } 5338 if (op != 0) { 5339 if (mod != 3) { 5340 gen_op_st_v(s, ot, s->T0, s->A0); 5341 } else { 5342 gen_op_mov_reg_v(s, ot, rm, s->T0); 5343 } 5344 } 5345 } 5346 5347 /* Delay all CC updates until after the store above. Note that 5348 C is the result of the test, Z is unchanged, and the others 5349 are all undefined. */ 5350 switch (s->cc_op) { 5351 case CC_OP_MULB ... CC_OP_MULQ: 5352 case CC_OP_ADDB ... CC_OP_ADDQ: 5353 case CC_OP_ADCB ... CC_OP_ADCQ: 5354 case CC_OP_SUBB ... CC_OP_SUBQ: 5355 case CC_OP_SBBB ... CC_OP_SBBQ: 5356 case CC_OP_LOGICB ... CC_OP_LOGICQ: 5357 case CC_OP_INCB ... CC_OP_INCQ: 5358 case CC_OP_DECB ... CC_OP_DECQ: 5359 case CC_OP_SHLB ... CC_OP_SHLQ: 5360 case CC_OP_SARB ... CC_OP_SARQ: 5361 case CC_OP_BMILGB ... CC_OP_BMILGQ: 5362 /* Z was going to be computed from the non-zero status of CC_DST. 5363 We can get that same Z value (and the new C value) by leaving 5364 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the 5365 same width. */ 5366 tcg_gen_mov_tl(cpu_cc_src, s->tmp4); 5367 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB); 5368 break; 5369 default: 5370 /* Otherwise, generate EFLAGS and replace the C bit. */ 5371 gen_compute_eflags(s); 5372 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4, 5373 ctz32(CC_C), 1); 5374 break; 5375 } 5376 break; 5377 case 0x1bc: /* bsf / tzcnt */ 5378 case 0x1bd: /* bsr / lzcnt */ 5379 ot = dflag; 5380 modrm = x86_ldub_code(env, s); 5381 reg = ((modrm >> 3) & 7) | REX_R(s); 5382 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 5383 gen_extu(ot, s->T0); 5384 5385 /* Note that lzcnt and tzcnt are in different extensions. */ 5386 if ((prefixes & PREFIX_REPZ) 5387 && (b & 1 5388 ? s->cpuid_ext3_features & CPUID_EXT3_ABM 5389 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) { 5390 int size = 8 << ot; 5391 /* For lzcnt/tzcnt, C bit is defined related to the input. */ 5392 tcg_gen_mov_tl(cpu_cc_src, s->T0); 5393 if (b & 1) { 5394 /* For lzcnt, reduce the target_ulong result by the 5395 number of zeros that we expect to find at the top. */ 5396 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS); 5397 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size); 5398 } else { 5399 /* For tzcnt, a zero input must return the operand size. */ 5400 tcg_gen_ctzi_tl(s->T0, s->T0, size); 5401 } 5402 /* For lzcnt/tzcnt, Z bit is defined related to the result. */ 5403 gen_op_update1_cc(s); 5404 set_cc_op(s, CC_OP_BMILGB + ot); 5405 } else { 5406 /* For bsr/bsf, only the Z bit is defined and it is related 5407 to the input and not the result. */ 5408 tcg_gen_mov_tl(cpu_cc_dst, s->T0); 5409 set_cc_op(s, CC_OP_LOGICB + ot); 5410 5411 /* ??? The manual says that the output is undefined when the 5412 input is zero, but real hardware leaves it unchanged, and 5413 real programs appear to depend on that. Accomplish this 5414 by passing the output as the value to return upon zero. */ 5415 if (b & 1) { 5416 /* For bsr, return the bit index of the first 1 bit, 5417 not the count of leading zeros. */ 5418 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1); 5419 tcg_gen_clz_tl(s->T0, s->T0, s->T1); 5420 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1); 5421 } else { 5422 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]); 5423 } 5424 } 5425 gen_op_mov_reg_v(s, ot, reg, s->T0); 5426 break; 5427 /************************/ 5428 /* bcd */ 5429 case 0x27: /* daa */ 5430 if (CODE64(s)) 5431 goto illegal_op; 5432 gen_update_cc_op(s); 5433 gen_helper_daa(cpu_env); 5434 set_cc_op(s, CC_OP_EFLAGS); 5435 break; 5436 case 0x2f: /* das */ 5437 if (CODE64(s)) 5438 goto illegal_op; 5439 gen_update_cc_op(s); 5440 gen_helper_das(cpu_env); 5441 set_cc_op(s, CC_OP_EFLAGS); 5442 break; 5443 case 0x37: /* aaa */ 5444 if (CODE64(s)) 5445 goto illegal_op; 5446 gen_update_cc_op(s); 5447 gen_helper_aaa(cpu_env); 5448 set_cc_op(s, CC_OP_EFLAGS); 5449 break; 5450 case 0x3f: /* aas */ 5451 if (CODE64(s)) 5452 goto illegal_op; 5453 gen_update_cc_op(s); 5454 gen_helper_aas(cpu_env); 5455 set_cc_op(s, CC_OP_EFLAGS); 5456 break; 5457 case 0xd4: /* aam */ 5458 if (CODE64(s)) 5459 goto illegal_op; 5460 val = x86_ldub_code(env, s); 5461 if (val == 0) { 5462 gen_exception(s, EXCP00_DIVZ); 5463 } else { 5464 gen_helper_aam(cpu_env, tcg_const_i32(val)); 5465 set_cc_op(s, CC_OP_LOGICB); 5466 } 5467 break; 5468 case 0xd5: /* aad */ 5469 if (CODE64(s)) 5470 goto illegal_op; 5471 val = x86_ldub_code(env, s); 5472 gen_helper_aad(cpu_env, tcg_const_i32(val)); 5473 set_cc_op(s, CC_OP_LOGICB); 5474 break; 5475 /************************/ 5476 /* misc */ 5477 case 0x90: /* nop */ 5478 /* XXX: correct lock test for all insn */ 5479 if (prefixes & PREFIX_LOCK) { 5480 goto illegal_op; 5481 } 5482 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */ 5483 if (REX_B(s)) { 5484 goto do_xchg_reg_eax; 5485 } 5486 if (prefixes & PREFIX_REPZ) { 5487 gen_update_cc_op(s); 5488 gen_update_eip_cur(s); 5489 gen_helper_pause(cpu_env, cur_insn_len_i32(s)); 5490 s->base.is_jmp = DISAS_NORETURN; 5491 } 5492 break; 5493 case 0x9b: /* fwait */ 5494 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == 5495 (HF_MP_MASK | HF_TS_MASK)) { 5496 gen_exception(s, EXCP07_PREX); 5497 } else { 5498 gen_helper_fwait(cpu_env); 5499 } 5500 break; 5501 case 0xcc: /* int3 */ 5502 gen_interrupt(s, EXCP03_INT3); 5503 break; 5504 case 0xcd: /* int N */ 5505 val = x86_ldub_code(env, s); 5506 if (check_vm86_iopl(s)) { 5507 gen_interrupt(s, val); 5508 } 5509 break; 5510 case 0xce: /* into */ 5511 if (CODE64(s)) 5512 goto illegal_op; 5513 gen_update_cc_op(s); 5514 gen_update_eip_cur(s); 5515 gen_helper_into(cpu_env, cur_insn_len_i32(s)); 5516 break; 5517 #ifdef WANT_ICEBP 5518 case 0xf1: /* icebp (undocumented, exits to external debugger) */ 5519 gen_svm_check_intercept(s, SVM_EXIT_ICEBP); 5520 gen_debug(s); 5521 break; 5522 #endif 5523 case 0xfa: /* cli */ 5524 if (check_iopl(s)) { 5525 gen_reset_eflags(s, IF_MASK); 5526 } 5527 break; 5528 case 0xfb: /* sti */ 5529 if (check_iopl(s)) { 5530 gen_set_eflags(s, IF_MASK); 5531 /* interruptions are enabled only the first insn after sti */ 5532 gen_update_eip_next(s); 5533 gen_eob_inhibit_irq(s, true); 5534 } 5535 break; 5536 case 0x62: /* bound */ 5537 if (CODE64(s)) 5538 goto illegal_op; 5539 ot = dflag; 5540 modrm = x86_ldub_code(env, s); 5541 reg = (modrm >> 3) & 7; 5542 mod = (modrm >> 6) & 3; 5543 if (mod == 3) 5544 goto illegal_op; 5545 gen_op_mov_v_reg(s, ot, s->T0, reg); 5546 gen_lea_modrm(env, s, modrm); 5547 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5548 if (ot == MO_16) { 5549 gen_helper_boundw(cpu_env, s->A0, s->tmp2_i32); 5550 } else { 5551 gen_helper_boundl(cpu_env, s->A0, s->tmp2_i32); 5552 } 5553 break; 5554 case 0x1c8 ... 0x1cf: /* bswap reg */ 5555 reg = (b & 7) | REX_B(s); 5556 #ifdef TARGET_X86_64 5557 if (dflag == MO_64) { 5558 tcg_gen_bswap64_i64(cpu_regs[reg], cpu_regs[reg]); 5559 break; 5560 } 5561 #endif 5562 tcg_gen_bswap32_tl(cpu_regs[reg], cpu_regs[reg], TCG_BSWAP_OZ); 5563 break; 5564 case 0xd6: /* salc */ 5565 if (CODE64(s)) 5566 goto illegal_op; 5567 gen_compute_eflags_c(s, s->T0); 5568 tcg_gen_neg_tl(s->T0, s->T0); 5569 gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0); 5570 break; 5571 case 0xe0: /* loopnz */ 5572 case 0xe1: /* loopz */ 5573 case 0xe2: /* loop */ 5574 case 0xe3: /* jecxz */ 5575 { 5576 TCGLabel *l1, *l2; 5577 int diff = (int8_t)insn_get(env, s, MO_8); 5578 5579 l1 = gen_new_label(); 5580 l2 = gen_new_label(); 5581 gen_update_cc_op(s); 5582 b &= 3; 5583 switch(b) { 5584 case 0: /* loopnz */ 5585 case 1: /* loopz */ 5586 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 5587 gen_op_jz_ecx(s, l2); 5588 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1); 5589 break; 5590 case 2: /* loop */ 5591 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 5592 gen_op_jnz_ecx(s, l1); 5593 break; 5594 default: 5595 case 3: /* jcxz */ 5596 gen_op_jz_ecx(s, l1); 5597 break; 5598 } 5599 5600 gen_set_label(l2); 5601 gen_jmp_rel_csize(s, 0, 1); 5602 5603 gen_set_label(l1); 5604 gen_jmp_rel(s, dflag, diff, 0); 5605 } 5606 break; 5607 case 0x130: /* wrmsr */ 5608 case 0x132: /* rdmsr */ 5609 if (check_cpl0(s)) { 5610 gen_update_cc_op(s); 5611 gen_update_eip_cur(s); 5612 if (b & 2) { 5613 gen_helper_rdmsr(cpu_env); 5614 } else { 5615 gen_helper_wrmsr(cpu_env); 5616 s->base.is_jmp = DISAS_EOB_NEXT; 5617 } 5618 } 5619 break; 5620 case 0x131: /* rdtsc */ 5621 gen_update_cc_op(s); 5622 gen_update_eip_cur(s); 5623 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 5624 gen_io_start(); 5625 s->base.is_jmp = DISAS_TOO_MANY; 5626 } 5627 gen_helper_rdtsc(cpu_env); 5628 break; 5629 case 0x133: /* rdpmc */ 5630 gen_update_cc_op(s); 5631 gen_update_eip_cur(s); 5632 gen_helper_rdpmc(cpu_env); 5633 s->base.is_jmp = DISAS_NORETURN; 5634 break; 5635 case 0x134: /* sysenter */ 5636 /* For Intel SYSENTER is valid on 64-bit */ 5637 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) 5638 goto illegal_op; 5639 if (!PE(s)) { 5640 gen_exception_gpf(s); 5641 } else { 5642 gen_helper_sysenter(cpu_env); 5643 s->base.is_jmp = DISAS_EOB_ONLY; 5644 } 5645 break; 5646 case 0x135: /* sysexit */ 5647 /* For Intel SYSEXIT is valid on 64-bit */ 5648 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) 5649 goto illegal_op; 5650 if (!PE(s)) { 5651 gen_exception_gpf(s); 5652 } else { 5653 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1)); 5654 s->base.is_jmp = DISAS_EOB_ONLY; 5655 } 5656 break; 5657 #ifdef TARGET_X86_64 5658 case 0x105: /* syscall */ 5659 /* XXX: is it usable in real mode ? */ 5660 gen_update_cc_op(s); 5661 gen_update_eip_cur(s); 5662 gen_helper_syscall(cpu_env, cur_insn_len_i32(s)); 5663 /* TF handling for the syscall insn is different. The TF bit is checked 5664 after the syscall insn completes. This allows #DB to not be 5665 generated after one has entered CPL0 if TF is set in FMASK. */ 5666 gen_eob_worker(s, false, true); 5667 break; 5668 case 0x107: /* sysret */ 5669 if (!PE(s)) { 5670 gen_exception_gpf(s); 5671 } else { 5672 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1)); 5673 /* condition codes are modified only in long mode */ 5674 if (LMA(s)) { 5675 set_cc_op(s, CC_OP_EFLAGS); 5676 } 5677 /* TF handling for the sysret insn is different. The TF bit is 5678 checked after the sysret insn completes. This allows #DB to be 5679 generated "as if" the syscall insn in userspace has just 5680 completed. */ 5681 gen_eob_worker(s, false, true); 5682 } 5683 break; 5684 #endif 5685 case 0x1a2: /* cpuid */ 5686 gen_update_cc_op(s); 5687 gen_update_eip_cur(s); 5688 gen_helper_cpuid(cpu_env); 5689 break; 5690 case 0xf4: /* hlt */ 5691 if (check_cpl0(s)) { 5692 gen_update_cc_op(s); 5693 gen_update_eip_cur(s); 5694 gen_helper_hlt(cpu_env, cur_insn_len_i32(s)); 5695 s->base.is_jmp = DISAS_NORETURN; 5696 } 5697 break; 5698 case 0x100: 5699 modrm = x86_ldub_code(env, s); 5700 mod = (modrm >> 6) & 3; 5701 op = (modrm >> 3) & 7; 5702 switch(op) { 5703 case 0: /* sldt */ 5704 if (!PE(s) || VM86(s)) 5705 goto illegal_op; 5706 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 5707 break; 5708 } 5709 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ); 5710 tcg_gen_ld32u_tl(s->T0, cpu_env, 5711 offsetof(CPUX86State, ldt.selector)); 5712 ot = mod == 3 ? dflag : MO_16; 5713 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 5714 break; 5715 case 2: /* lldt */ 5716 if (!PE(s) || VM86(s)) 5717 goto illegal_op; 5718 if (check_cpl0(s)) { 5719 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE); 5720 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 5721 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5722 gen_helper_lldt(cpu_env, s->tmp2_i32); 5723 } 5724 break; 5725 case 1: /* str */ 5726 if (!PE(s) || VM86(s)) 5727 goto illegal_op; 5728 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 5729 break; 5730 } 5731 gen_svm_check_intercept(s, SVM_EXIT_TR_READ); 5732 tcg_gen_ld32u_tl(s->T0, cpu_env, 5733 offsetof(CPUX86State, tr.selector)); 5734 ot = mod == 3 ? dflag : MO_16; 5735 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 5736 break; 5737 case 3: /* ltr */ 5738 if (!PE(s) || VM86(s)) 5739 goto illegal_op; 5740 if (check_cpl0(s)) { 5741 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE); 5742 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 5743 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 5744 gen_helper_ltr(cpu_env, s->tmp2_i32); 5745 } 5746 break; 5747 case 4: /* verr */ 5748 case 5: /* verw */ 5749 if (!PE(s) || VM86(s)) 5750 goto illegal_op; 5751 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 5752 gen_update_cc_op(s); 5753 if (op == 4) { 5754 gen_helper_verr(cpu_env, s->T0); 5755 } else { 5756 gen_helper_verw(cpu_env, s->T0); 5757 } 5758 set_cc_op(s, CC_OP_EFLAGS); 5759 break; 5760 default: 5761 goto unknown_op; 5762 } 5763 break; 5764 5765 case 0x101: 5766 modrm = x86_ldub_code(env, s); 5767 switch (modrm) { 5768 CASE_MODRM_MEM_OP(0): /* sgdt */ 5769 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 5770 break; 5771 } 5772 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ); 5773 gen_lea_modrm(env, s, modrm); 5774 tcg_gen_ld32u_tl(s->T0, 5775 cpu_env, offsetof(CPUX86State, gdt.limit)); 5776 gen_op_st_v(s, MO_16, s->T0, s->A0); 5777 gen_add_A0_im(s, 2); 5778 tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base)); 5779 if (dflag == MO_16) { 5780 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 5781 } 5782 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 5783 break; 5784 5785 case 0xc8: /* monitor */ 5786 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 5787 goto illegal_op; 5788 } 5789 gen_update_cc_op(s); 5790 gen_update_eip_cur(s); 5791 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 5792 gen_extu(s->aflag, s->A0); 5793 gen_add_A0_ds_seg(s); 5794 gen_helper_monitor(cpu_env, s->A0); 5795 break; 5796 5797 case 0xc9: /* mwait */ 5798 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 5799 goto illegal_op; 5800 } 5801 gen_update_cc_op(s); 5802 gen_update_eip_cur(s); 5803 gen_helper_mwait(cpu_env, cur_insn_len_i32(s)); 5804 s->base.is_jmp = DISAS_NORETURN; 5805 break; 5806 5807 case 0xca: /* clac */ 5808 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 5809 || CPL(s) != 0) { 5810 goto illegal_op; 5811 } 5812 gen_reset_eflags(s, AC_MASK); 5813 s->base.is_jmp = DISAS_EOB_NEXT; 5814 break; 5815 5816 case 0xcb: /* stac */ 5817 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 5818 || CPL(s) != 0) { 5819 goto illegal_op; 5820 } 5821 gen_set_eflags(s, AC_MASK); 5822 s->base.is_jmp = DISAS_EOB_NEXT; 5823 break; 5824 5825 CASE_MODRM_MEM_OP(1): /* sidt */ 5826 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 5827 break; 5828 } 5829 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ); 5830 gen_lea_modrm(env, s, modrm); 5831 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit)); 5832 gen_op_st_v(s, MO_16, s->T0, s->A0); 5833 gen_add_A0_im(s, 2); 5834 tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base)); 5835 if (dflag == MO_16) { 5836 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 5837 } 5838 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 5839 break; 5840 5841 case 0xd0: /* xgetbv */ 5842 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 5843 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 5844 | PREFIX_REPZ | PREFIX_REPNZ))) { 5845 goto illegal_op; 5846 } 5847 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 5848 gen_helper_xgetbv(s->tmp1_i64, cpu_env, s->tmp2_i32); 5849 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 5850 break; 5851 5852 case 0xd1: /* xsetbv */ 5853 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 5854 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 5855 | PREFIX_REPZ | PREFIX_REPNZ))) { 5856 goto illegal_op; 5857 } 5858 if (!check_cpl0(s)) { 5859 break; 5860 } 5861 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 5862 cpu_regs[R_EDX]); 5863 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 5864 gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64); 5865 /* End TB because translation flags may change. */ 5866 s->base.is_jmp = DISAS_EOB_NEXT; 5867 break; 5868 5869 case 0xd8: /* VMRUN */ 5870 if (!SVME(s) || !PE(s)) { 5871 goto illegal_op; 5872 } 5873 if (!check_cpl0(s)) { 5874 break; 5875 } 5876 gen_update_cc_op(s); 5877 gen_update_eip_cur(s); 5878 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1), 5879 cur_insn_len_i32(s)); 5880 tcg_gen_exit_tb(NULL, 0); 5881 s->base.is_jmp = DISAS_NORETURN; 5882 break; 5883 5884 case 0xd9: /* VMMCALL */ 5885 if (!SVME(s)) { 5886 goto illegal_op; 5887 } 5888 gen_update_cc_op(s); 5889 gen_update_eip_cur(s); 5890 gen_helper_vmmcall(cpu_env); 5891 break; 5892 5893 case 0xda: /* VMLOAD */ 5894 if (!SVME(s) || !PE(s)) { 5895 goto illegal_op; 5896 } 5897 if (!check_cpl0(s)) { 5898 break; 5899 } 5900 gen_update_cc_op(s); 5901 gen_update_eip_cur(s); 5902 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1)); 5903 break; 5904 5905 case 0xdb: /* VMSAVE */ 5906 if (!SVME(s) || !PE(s)) { 5907 goto illegal_op; 5908 } 5909 if (!check_cpl0(s)) { 5910 break; 5911 } 5912 gen_update_cc_op(s); 5913 gen_update_eip_cur(s); 5914 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1)); 5915 break; 5916 5917 case 0xdc: /* STGI */ 5918 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 5919 || !PE(s)) { 5920 goto illegal_op; 5921 } 5922 if (!check_cpl0(s)) { 5923 break; 5924 } 5925 gen_update_cc_op(s); 5926 gen_helper_stgi(cpu_env); 5927 s->base.is_jmp = DISAS_EOB_NEXT; 5928 break; 5929 5930 case 0xdd: /* CLGI */ 5931 if (!SVME(s) || !PE(s)) { 5932 goto illegal_op; 5933 } 5934 if (!check_cpl0(s)) { 5935 break; 5936 } 5937 gen_update_cc_op(s); 5938 gen_update_eip_cur(s); 5939 gen_helper_clgi(cpu_env); 5940 break; 5941 5942 case 0xde: /* SKINIT */ 5943 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 5944 || !PE(s)) { 5945 goto illegal_op; 5946 } 5947 gen_svm_check_intercept(s, SVM_EXIT_SKINIT); 5948 /* If not intercepted, not implemented -- raise #UD. */ 5949 goto illegal_op; 5950 5951 case 0xdf: /* INVLPGA */ 5952 if (!SVME(s) || !PE(s)) { 5953 goto illegal_op; 5954 } 5955 if (!check_cpl0(s)) { 5956 break; 5957 } 5958 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA); 5959 if (s->aflag == MO_64) { 5960 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 5961 } else { 5962 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]); 5963 } 5964 gen_helper_flush_page(cpu_env, s->A0); 5965 s->base.is_jmp = DISAS_EOB_NEXT; 5966 break; 5967 5968 CASE_MODRM_MEM_OP(2): /* lgdt */ 5969 if (!check_cpl0(s)) { 5970 break; 5971 } 5972 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE); 5973 gen_lea_modrm(env, s, modrm); 5974 gen_op_ld_v(s, MO_16, s->T1, s->A0); 5975 gen_add_A0_im(s, 2); 5976 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 5977 if (dflag == MO_16) { 5978 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 5979 } 5980 tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base)); 5981 tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, gdt.limit)); 5982 break; 5983 5984 CASE_MODRM_MEM_OP(3): /* lidt */ 5985 if (!check_cpl0(s)) { 5986 break; 5987 } 5988 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE); 5989 gen_lea_modrm(env, s, modrm); 5990 gen_op_ld_v(s, MO_16, s->T1, s->A0); 5991 gen_add_A0_im(s, 2); 5992 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 5993 if (dflag == MO_16) { 5994 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 5995 } 5996 tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base)); 5997 tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, idt.limit)); 5998 break; 5999 6000 CASE_MODRM_OP(4): /* smsw */ 6001 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 6002 break; 6003 } 6004 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0); 6005 tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0])); 6006 /* 6007 * In 32-bit mode, the higher 16 bits of the destination 6008 * register are undefined. In practice CR0[31:0] is stored 6009 * just like in 64-bit mode. 6010 */ 6011 mod = (modrm >> 6) & 3; 6012 ot = (mod != 3 ? MO_16 : s->dflag); 6013 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 6014 break; 6015 case 0xee: /* rdpkru */ 6016 if (prefixes & PREFIX_LOCK) { 6017 goto illegal_op; 6018 } 6019 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 6020 gen_helper_rdpkru(s->tmp1_i64, cpu_env, s->tmp2_i32); 6021 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 6022 break; 6023 case 0xef: /* wrpkru */ 6024 if (prefixes & PREFIX_LOCK) { 6025 goto illegal_op; 6026 } 6027 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 6028 cpu_regs[R_EDX]); 6029 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 6030 gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64); 6031 break; 6032 6033 CASE_MODRM_OP(6): /* lmsw */ 6034 if (!check_cpl0(s)) { 6035 break; 6036 } 6037 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 6038 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 6039 /* 6040 * Only the 4 lower bits of CR0 are modified. 6041 * PE cannot be set to zero if already set to one. 6042 */ 6043 tcg_gen_ld_tl(s->T1, cpu_env, offsetof(CPUX86State, cr[0])); 6044 tcg_gen_andi_tl(s->T0, s->T0, 0xf); 6045 tcg_gen_andi_tl(s->T1, s->T1, ~0xe); 6046 tcg_gen_or_tl(s->T0, s->T0, s->T1); 6047 gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0); 6048 s->base.is_jmp = DISAS_EOB_NEXT; 6049 break; 6050 6051 CASE_MODRM_MEM_OP(7): /* invlpg */ 6052 if (!check_cpl0(s)) { 6053 break; 6054 } 6055 gen_svm_check_intercept(s, SVM_EXIT_INVLPG); 6056 gen_lea_modrm(env, s, modrm); 6057 gen_helper_flush_page(cpu_env, s->A0); 6058 s->base.is_jmp = DISAS_EOB_NEXT; 6059 break; 6060 6061 case 0xf8: /* swapgs */ 6062 #ifdef TARGET_X86_64 6063 if (CODE64(s)) { 6064 if (check_cpl0(s)) { 6065 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]); 6066 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env, 6067 offsetof(CPUX86State, kernelgsbase)); 6068 tcg_gen_st_tl(s->T0, cpu_env, 6069 offsetof(CPUX86State, kernelgsbase)); 6070 } 6071 break; 6072 } 6073 #endif 6074 goto illegal_op; 6075 6076 case 0xf9: /* rdtscp */ 6077 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) { 6078 goto illegal_op; 6079 } 6080 gen_update_cc_op(s); 6081 gen_update_eip_cur(s); 6082 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6083 gen_io_start(); 6084 s->base.is_jmp = DISAS_TOO_MANY; 6085 } 6086 gen_helper_rdtscp(cpu_env); 6087 break; 6088 6089 default: 6090 goto unknown_op; 6091 } 6092 break; 6093 6094 case 0x108: /* invd */ 6095 case 0x109: /* wbinvd */ 6096 if (check_cpl0(s)) { 6097 gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD); 6098 /* nothing to do */ 6099 } 6100 break; 6101 case 0x63: /* arpl or movslS (x86_64) */ 6102 #ifdef TARGET_X86_64 6103 if (CODE64(s)) { 6104 int d_ot; 6105 /* d_ot is the size of destination */ 6106 d_ot = dflag; 6107 6108 modrm = x86_ldub_code(env, s); 6109 reg = ((modrm >> 3) & 7) | REX_R(s); 6110 mod = (modrm >> 6) & 3; 6111 rm = (modrm & 7) | REX_B(s); 6112 6113 if (mod == 3) { 6114 gen_op_mov_v_reg(s, MO_32, s->T0, rm); 6115 /* sign extend */ 6116 if (d_ot == MO_64) { 6117 tcg_gen_ext32s_tl(s->T0, s->T0); 6118 } 6119 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 6120 } else { 6121 gen_lea_modrm(env, s, modrm); 6122 gen_op_ld_v(s, MO_32 | MO_SIGN, s->T0, s->A0); 6123 gen_op_mov_reg_v(s, d_ot, reg, s->T0); 6124 } 6125 } else 6126 #endif 6127 { 6128 TCGLabel *label1; 6129 TCGv t0, t1, t2, a0; 6130 6131 if (!PE(s) || VM86(s)) 6132 goto illegal_op; 6133 t0 = tcg_temp_local_new(); 6134 t1 = tcg_temp_local_new(); 6135 t2 = tcg_temp_local_new(); 6136 ot = MO_16; 6137 modrm = x86_ldub_code(env, s); 6138 reg = (modrm >> 3) & 7; 6139 mod = (modrm >> 6) & 3; 6140 rm = modrm & 7; 6141 if (mod != 3) { 6142 gen_lea_modrm(env, s, modrm); 6143 gen_op_ld_v(s, ot, t0, s->A0); 6144 a0 = tcg_temp_local_new(); 6145 tcg_gen_mov_tl(a0, s->A0); 6146 } else { 6147 gen_op_mov_v_reg(s, ot, t0, rm); 6148 a0 = NULL; 6149 } 6150 gen_op_mov_v_reg(s, ot, t1, reg); 6151 tcg_gen_andi_tl(s->tmp0, t0, 3); 6152 tcg_gen_andi_tl(t1, t1, 3); 6153 tcg_gen_movi_tl(t2, 0); 6154 label1 = gen_new_label(); 6155 tcg_gen_brcond_tl(TCG_COND_GE, s->tmp0, t1, label1); 6156 tcg_gen_andi_tl(t0, t0, ~3); 6157 tcg_gen_or_tl(t0, t0, t1); 6158 tcg_gen_movi_tl(t2, CC_Z); 6159 gen_set_label(label1); 6160 if (mod != 3) { 6161 gen_op_st_v(s, ot, t0, a0); 6162 tcg_temp_free(a0); 6163 } else { 6164 gen_op_mov_reg_v(s, ot, rm, t0); 6165 } 6166 gen_compute_eflags(s); 6167 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z); 6168 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2); 6169 tcg_temp_free(t0); 6170 tcg_temp_free(t1); 6171 tcg_temp_free(t2); 6172 } 6173 break; 6174 case 0x102: /* lar */ 6175 case 0x103: /* lsl */ 6176 { 6177 TCGLabel *label1; 6178 TCGv t0; 6179 if (!PE(s) || VM86(s)) 6180 goto illegal_op; 6181 ot = dflag != MO_16 ? MO_32 : MO_16; 6182 modrm = x86_ldub_code(env, s); 6183 reg = ((modrm >> 3) & 7) | REX_R(s); 6184 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); 6185 t0 = tcg_temp_local_new(); 6186 gen_update_cc_op(s); 6187 if (b == 0x102) { 6188 gen_helper_lar(t0, cpu_env, s->T0); 6189 } else { 6190 gen_helper_lsl(t0, cpu_env, s->T0); 6191 } 6192 tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z); 6193 label1 = gen_new_label(); 6194 tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1); 6195 gen_op_mov_reg_v(s, ot, reg, t0); 6196 gen_set_label(label1); 6197 set_cc_op(s, CC_OP_EFLAGS); 6198 tcg_temp_free(t0); 6199 } 6200 break; 6201 case 0x118: 6202 modrm = x86_ldub_code(env, s); 6203 mod = (modrm >> 6) & 3; 6204 op = (modrm >> 3) & 7; 6205 switch(op) { 6206 case 0: /* prefetchnta */ 6207 case 1: /* prefetchnt0 */ 6208 case 2: /* prefetchnt0 */ 6209 case 3: /* prefetchnt0 */ 6210 if (mod == 3) 6211 goto illegal_op; 6212 gen_nop_modrm(env, s, modrm); 6213 /* nothing more to do */ 6214 break; 6215 default: /* nop (multi byte) */ 6216 gen_nop_modrm(env, s, modrm); 6217 break; 6218 } 6219 break; 6220 case 0x11a: 6221 modrm = x86_ldub_code(env, s); 6222 if (s->flags & HF_MPX_EN_MASK) { 6223 mod = (modrm >> 6) & 3; 6224 reg = ((modrm >> 3) & 7) | REX_R(s); 6225 if (prefixes & PREFIX_REPZ) { 6226 /* bndcl */ 6227 if (reg >= 4 6228 || (prefixes & PREFIX_LOCK) 6229 || s->aflag == MO_16) { 6230 goto illegal_op; 6231 } 6232 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]); 6233 } else if (prefixes & PREFIX_REPNZ) { 6234 /* bndcu */ 6235 if (reg >= 4 6236 || (prefixes & PREFIX_LOCK) 6237 || s->aflag == MO_16) { 6238 goto illegal_op; 6239 } 6240 TCGv_i64 notu = tcg_temp_new_i64(); 6241 tcg_gen_not_i64(notu, cpu_bndu[reg]); 6242 gen_bndck(env, s, modrm, TCG_COND_GTU, notu); 6243 tcg_temp_free_i64(notu); 6244 } else if (prefixes & PREFIX_DATA) { 6245 /* bndmov -- from reg/mem */ 6246 if (reg >= 4 || s->aflag == MO_16) { 6247 goto illegal_op; 6248 } 6249 if (mod == 3) { 6250 int reg2 = (modrm & 7) | REX_B(s); 6251 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 6252 goto illegal_op; 6253 } 6254 if (s->flags & HF_MPX_IU_MASK) { 6255 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]); 6256 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]); 6257 } 6258 } else { 6259 gen_lea_modrm(env, s, modrm); 6260 if (CODE64(s)) { 6261 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 6262 s->mem_index, MO_LEUQ); 6263 tcg_gen_addi_tl(s->A0, s->A0, 8); 6264 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 6265 s->mem_index, MO_LEUQ); 6266 } else { 6267 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 6268 s->mem_index, MO_LEUL); 6269 tcg_gen_addi_tl(s->A0, s->A0, 4); 6270 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 6271 s->mem_index, MO_LEUL); 6272 } 6273 /* bnd registers are now in-use */ 6274 gen_set_hflag(s, HF_MPX_IU_MASK); 6275 } 6276 } else if (mod != 3) { 6277 /* bndldx */ 6278 AddressParts a = gen_lea_modrm_0(env, s, modrm); 6279 if (reg >= 4 6280 || (prefixes & PREFIX_LOCK) 6281 || s->aflag == MO_16 6282 || a.base < -1) { 6283 goto illegal_op; 6284 } 6285 if (a.base >= 0) { 6286 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 6287 } else { 6288 tcg_gen_movi_tl(s->A0, 0); 6289 } 6290 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 6291 if (a.index >= 0) { 6292 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 6293 } else { 6294 tcg_gen_movi_tl(s->T0, 0); 6295 } 6296 if (CODE64(s)) { 6297 gen_helper_bndldx64(cpu_bndl[reg], cpu_env, s->A0, s->T0); 6298 tcg_gen_ld_i64(cpu_bndu[reg], cpu_env, 6299 offsetof(CPUX86State, mmx_t0.MMX_Q(0))); 6300 } else { 6301 gen_helper_bndldx32(cpu_bndu[reg], cpu_env, s->A0, s->T0); 6302 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]); 6303 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32); 6304 } 6305 gen_set_hflag(s, HF_MPX_IU_MASK); 6306 } 6307 } 6308 gen_nop_modrm(env, s, modrm); 6309 break; 6310 case 0x11b: 6311 modrm = x86_ldub_code(env, s); 6312 if (s->flags & HF_MPX_EN_MASK) { 6313 mod = (modrm >> 6) & 3; 6314 reg = ((modrm >> 3) & 7) | REX_R(s); 6315 if (mod != 3 && (prefixes & PREFIX_REPZ)) { 6316 /* bndmk */ 6317 if (reg >= 4 6318 || (prefixes & PREFIX_LOCK) 6319 || s->aflag == MO_16) { 6320 goto illegal_op; 6321 } 6322 AddressParts a = gen_lea_modrm_0(env, s, modrm); 6323 if (a.base >= 0) { 6324 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]); 6325 if (!CODE64(s)) { 6326 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]); 6327 } 6328 } else if (a.base == -1) { 6329 /* no base register has lower bound of 0 */ 6330 tcg_gen_movi_i64(cpu_bndl[reg], 0); 6331 } else { 6332 /* rip-relative generates #ud */ 6333 goto illegal_op; 6334 } 6335 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false)); 6336 if (!CODE64(s)) { 6337 tcg_gen_ext32u_tl(s->A0, s->A0); 6338 } 6339 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0); 6340 /* bnd registers are now in-use */ 6341 gen_set_hflag(s, HF_MPX_IU_MASK); 6342 break; 6343 } else if (prefixes & PREFIX_REPNZ) { 6344 /* bndcn */ 6345 if (reg >= 4 6346 || (prefixes & PREFIX_LOCK) 6347 || s->aflag == MO_16) { 6348 goto illegal_op; 6349 } 6350 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]); 6351 } else if (prefixes & PREFIX_DATA) { 6352 /* bndmov -- to reg/mem */ 6353 if (reg >= 4 || s->aflag == MO_16) { 6354 goto illegal_op; 6355 } 6356 if (mod == 3) { 6357 int reg2 = (modrm & 7) | REX_B(s); 6358 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 6359 goto illegal_op; 6360 } 6361 if (s->flags & HF_MPX_IU_MASK) { 6362 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]); 6363 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]); 6364 } 6365 } else { 6366 gen_lea_modrm(env, s, modrm); 6367 if (CODE64(s)) { 6368 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 6369 s->mem_index, MO_LEUQ); 6370 tcg_gen_addi_tl(s->A0, s->A0, 8); 6371 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 6372 s->mem_index, MO_LEUQ); 6373 } else { 6374 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 6375 s->mem_index, MO_LEUL); 6376 tcg_gen_addi_tl(s->A0, s->A0, 4); 6377 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 6378 s->mem_index, MO_LEUL); 6379 } 6380 } 6381 } else if (mod != 3) { 6382 /* bndstx */ 6383 AddressParts a = gen_lea_modrm_0(env, s, modrm); 6384 if (reg >= 4 6385 || (prefixes & PREFIX_LOCK) 6386 || s->aflag == MO_16 6387 || a.base < -1) { 6388 goto illegal_op; 6389 } 6390 if (a.base >= 0) { 6391 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 6392 } else { 6393 tcg_gen_movi_tl(s->A0, 0); 6394 } 6395 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override); 6396 if (a.index >= 0) { 6397 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 6398 } else { 6399 tcg_gen_movi_tl(s->T0, 0); 6400 } 6401 if (CODE64(s)) { 6402 gen_helper_bndstx64(cpu_env, s->A0, s->T0, 6403 cpu_bndl[reg], cpu_bndu[reg]); 6404 } else { 6405 gen_helper_bndstx32(cpu_env, s->A0, s->T0, 6406 cpu_bndl[reg], cpu_bndu[reg]); 6407 } 6408 } 6409 } 6410 gen_nop_modrm(env, s, modrm); 6411 break; 6412 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */ 6413 modrm = x86_ldub_code(env, s); 6414 gen_nop_modrm(env, s, modrm); 6415 break; 6416 6417 case 0x120: /* mov reg, crN */ 6418 case 0x122: /* mov crN, reg */ 6419 if (!check_cpl0(s)) { 6420 break; 6421 } 6422 modrm = x86_ldub_code(env, s); 6423 /* 6424 * Ignore the mod bits (assume (modrm&0xc0)==0xc0). 6425 * AMD documentation (24594.pdf) and testing of Intel 386 and 486 6426 * processors all show that the mod bits are assumed to be 1's, 6427 * regardless of actual values. 6428 */ 6429 rm = (modrm & 7) | REX_B(s); 6430 reg = ((modrm >> 3) & 7) | REX_R(s); 6431 switch (reg) { 6432 case 0: 6433 if ((prefixes & PREFIX_LOCK) && 6434 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) { 6435 reg = 8; 6436 } 6437 break; 6438 case 2: 6439 case 3: 6440 case 4: 6441 case 8: 6442 break; 6443 default: 6444 goto unknown_op; 6445 } 6446 ot = (CODE64(s) ? MO_64 : MO_32); 6447 6448 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) { 6449 gen_io_start(); 6450 s->base.is_jmp = DISAS_TOO_MANY; 6451 } 6452 if (b & 2) { 6453 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg); 6454 gen_op_mov_v_reg(s, ot, s->T0, rm); 6455 gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0); 6456 s->base.is_jmp = DISAS_EOB_NEXT; 6457 } else { 6458 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg); 6459 gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg)); 6460 gen_op_mov_reg_v(s, ot, rm, s->T0); 6461 } 6462 break; 6463 6464 case 0x121: /* mov reg, drN */ 6465 case 0x123: /* mov drN, reg */ 6466 if (check_cpl0(s)) { 6467 modrm = x86_ldub_code(env, s); 6468 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). 6469 * AMD documentation (24594.pdf) and testing of 6470 * intel 386 and 486 processors all show that the mod bits 6471 * are assumed to be 1's, regardless of actual values. 6472 */ 6473 rm = (modrm & 7) | REX_B(s); 6474 reg = ((modrm >> 3) & 7) | REX_R(s); 6475 if (CODE64(s)) 6476 ot = MO_64; 6477 else 6478 ot = MO_32; 6479 if (reg >= 8) { 6480 goto illegal_op; 6481 } 6482 if (b & 2) { 6483 gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg); 6484 gen_op_mov_v_reg(s, ot, s->T0, rm); 6485 tcg_gen_movi_i32(s->tmp2_i32, reg); 6486 gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0); 6487 s->base.is_jmp = DISAS_EOB_NEXT; 6488 } else { 6489 gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg); 6490 tcg_gen_movi_i32(s->tmp2_i32, reg); 6491 gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32); 6492 gen_op_mov_reg_v(s, ot, rm, s->T0); 6493 } 6494 } 6495 break; 6496 case 0x106: /* clts */ 6497 if (check_cpl0(s)) { 6498 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 6499 gen_helper_clts(cpu_env); 6500 /* abort block because static cpu state changed */ 6501 s->base.is_jmp = DISAS_EOB_NEXT; 6502 } 6503 break; 6504 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */ 6505 case 0x1c3: /* MOVNTI reg, mem */ 6506 if (!(s->cpuid_features & CPUID_SSE2)) 6507 goto illegal_op; 6508 ot = mo_64_32(dflag); 6509 modrm = x86_ldub_code(env, s); 6510 mod = (modrm >> 6) & 3; 6511 if (mod == 3) 6512 goto illegal_op; 6513 reg = ((modrm >> 3) & 7) | REX_R(s); 6514 /* generate a generic store */ 6515 gen_ldst_modrm(env, s, modrm, ot, reg, 1); 6516 break; 6517 case 0x1ae: 6518 modrm = x86_ldub_code(env, s); 6519 switch (modrm) { 6520 CASE_MODRM_MEM_OP(0): /* fxsave */ 6521 if (!(s->cpuid_features & CPUID_FXSR) 6522 || (prefixes & PREFIX_LOCK)) { 6523 goto illegal_op; 6524 } 6525 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 6526 gen_exception(s, EXCP07_PREX); 6527 break; 6528 } 6529 gen_lea_modrm(env, s, modrm); 6530 gen_helper_fxsave(cpu_env, s->A0); 6531 break; 6532 6533 CASE_MODRM_MEM_OP(1): /* fxrstor */ 6534 if (!(s->cpuid_features & CPUID_FXSR) 6535 || (prefixes & PREFIX_LOCK)) { 6536 goto illegal_op; 6537 } 6538 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { 6539 gen_exception(s, EXCP07_PREX); 6540 break; 6541 } 6542 gen_lea_modrm(env, s, modrm); 6543 gen_helper_fxrstor(cpu_env, s->A0); 6544 break; 6545 6546 CASE_MODRM_MEM_OP(2): /* ldmxcsr */ 6547 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 6548 goto illegal_op; 6549 } 6550 if (s->flags & HF_TS_MASK) { 6551 gen_exception(s, EXCP07_PREX); 6552 break; 6553 } 6554 gen_lea_modrm(env, s, modrm); 6555 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL); 6556 gen_helper_ldmxcsr(cpu_env, s->tmp2_i32); 6557 break; 6558 6559 CASE_MODRM_MEM_OP(3): /* stmxcsr */ 6560 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) { 6561 goto illegal_op; 6562 } 6563 if (s->flags & HF_TS_MASK) { 6564 gen_exception(s, EXCP07_PREX); 6565 break; 6566 } 6567 gen_helper_update_mxcsr(cpu_env); 6568 gen_lea_modrm(env, s, modrm); 6569 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, mxcsr)); 6570 gen_op_st_v(s, MO_32, s->T0, s->A0); 6571 break; 6572 6573 CASE_MODRM_MEM_OP(4): /* xsave */ 6574 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 6575 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 6576 | PREFIX_REPZ | PREFIX_REPNZ))) { 6577 goto illegal_op; 6578 } 6579 gen_lea_modrm(env, s, modrm); 6580 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 6581 cpu_regs[R_EDX]); 6582 gen_helper_xsave(cpu_env, s->A0, s->tmp1_i64); 6583 break; 6584 6585 CASE_MODRM_MEM_OP(5): /* xrstor */ 6586 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 6587 || (prefixes & (PREFIX_LOCK | PREFIX_DATA 6588 | PREFIX_REPZ | PREFIX_REPNZ))) { 6589 goto illegal_op; 6590 } 6591 gen_lea_modrm(env, s, modrm); 6592 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 6593 cpu_regs[R_EDX]); 6594 gen_helper_xrstor(cpu_env, s->A0, s->tmp1_i64); 6595 /* XRSTOR is how MPX is enabled, which changes how 6596 we translate. Thus we need to end the TB. */ 6597 s->base.is_jmp = DISAS_EOB_NEXT; 6598 break; 6599 6600 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */ 6601 if (prefixes & PREFIX_LOCK) { 6602 goto illegal_op; 6603 } 6604 if (prefixes & PREFIX_DATA) { 6605 /* clwb */ 6606 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) { 6607 goto illegal_op; 6608 } 6609 gen_nop_modrm(env, s, modrm); 6610 } else { 6611 /* xsaveopt */ 6612 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 6613 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0 6614 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) { 6615 goto illegal_op; 6616 } 6617 gen_lea_modrm(env, s, modrm); 6618 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 6619 cpu_regs[R_EDX]); 6620 gen_helper_xsaveopt(cpu_env, s->A0, s->tmp1_i64); 6621 } 6622 break; 6623 6624 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */ 6625 if (prefixes & PREFIX_LOCK) { 6626 goto illegal_op; 6627 } 6628 if (prefixes & PREFIX_DATA) { 6629 /* clflushopt */ 6630 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) { 6631 goto illegal_op; 6632 } 6633 } else { 6634 /* clflush */ 6635 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) 6636 || !(s->cpuid_features & CPUID_CLFLUSH)) { 6637 goto illegal_op; 6638 } 6639 } 6640 gen_nop_modrm(env, s, modrm); 6641 break; 6642 6643 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */ 6644 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */ 6645 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */ 6646 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */ 6647 if (CODE64(s) 6648 && (prefixes & PREFIX_REPZ) 6649 && !(prefixes & PREFIX_LOCK) 6650 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) { 6651 TCGv base, treg, src, dst; 6652 6653 /* Preserve hflags bits by testing CR4 at runtime. */ 6654 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK); 6655 gen_helper_cr4_testbit(cpu_env, s->tmp2_i32); 6656 6657 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS]; 6658 treg = cpu_regs[(modrm & 7) | REX_B(s)]; 6659 6660 if (modrm & 0x10) { 6661 /* wr*base */ 6662 dst = base, src = treg; 6663 } else { 6664 /* rd*base */ 6665 dst = treg, src = base; 6666 } 6667 6668 if (s->dflag == MO_32) { 6669 tcg_gen_ext32u_tl(dst, src); 6670 } else { 6671 tcg_gen_mov_tl(dst, src); 6672 } 6673 break; 6674 } 6675 goto unknown_op; 6676 6677 case 0xf8: /* sfence / pcommit */ 6678 if (prefixes & PREFIX_DATA) { 6679 /* pcommit */ 6680 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT) 6681 || (prefixes & PREFIX_LOCK)) { 6682 goto illegal_op; 6683 } 6684 break; 6685 } 6686 /* fallthru */ 6687 case 0xf9 ... 0xff: /* sfence */ 6688 if (!(s->cpuid_features & CPUID_SSE) 6689 || (prefixes & PREFIX_LOCK)) { 6690 goto illegal_op; 6691 } 6692 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC); 6693 break; 6694 case 0xe8 ... 0xef: /* lfence */ 6695 if (!(s->cpuid_features & CPUID_SSE) 6696 || (prefixes & PREFIX_LOCK)) { 6697 goto illegal_op; 6698 } 6699 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC); 6700 break; 6701 case 0xf0 ... 0xf7: /* mfence */ 6702 if (!(s->cpuid_features & CPUID_SSE2) 6703 || (prefixes & PREFIX_LOCK)) { 6704 goto illegal_op; 6705 } 6706 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 6707 break; 6708 6709 default: 6710 goto unknown_op; 6711 } 6712 break; 6713 6714 case 0x10d: /* 3DNow! prefetch(w) */ 6715 modrm = x86_ldub_code(env, s); 6716 mod = (modrm >> 6) & 3; 6717 if (mod == 3) 6718 goto illegal_op; 6719 gen_nop_modrm(env, s, modrm); 6720 break; 6721 case 0x1aa: /* rsm */ 6722 gen_svm_check_intercept(s, SVM_EXIT_RSM); 6723 if (!(s->flags & HF_SMM_MASK)) 6724 goto illegal_op; 6725 #ifdef CONFIG_USER_ONLY 6726 /* we should not be in SMM mode */ 6727 g_assert_not_reached(); 6728 #else 6729 gen_update_cc_op(s); 6730 gen_update_eip_next(s); 6731 gen_helper_rsm(cpu_env); 6732 #endif /* CONFIG_USER_ONLY */ 6733 s->base.is_jmp = DISAS_EOB_ONLY; 6734 break; 6735 case 0x1b8: /* SSE4.2 popcnt */ 6736 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) != 6737 PREFIX_REPZ) 6738 goto illegal_op; 6739 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT)) 6740 goto illegal_op; 6741 6742 modrm = x86_ldub_code(env, s); 6743 reg = ((modrm >> 3) & 7) | REX_R(s); 6744 6745 if (s->prefix & PREFIX_DATA) { 6746 ot = MO_16; 6747 } else { 6748 ot = mo_64_32(dflag); 6749 } 6750 6751 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 6752 gen_extu(ot, s->T0); 6753 tcg_gen_mov_tl(cpu_cc_src, s->T0); 6754 tcg_gen_ctpop_tl(s->T0, s->T0); 6755 gen_op_mov_reg_v(s, ot, reg, s->T0); 6756 6757 set_cc_op(s, CC_OP_POPCNT); 6758 break; 6759 case 0x10e ... 0x117: 6760 case 0x128 ... 0x12f: 6761 case 0x138 ... 0x13a: 6762 case 0x150 ... 0x179: 6763 case 0x17c ... 0x17f: 6764 case 0x1c2: 6765 case 0x1c4 ... 0x1c6: 6766 case 0x1d0 ... 0x1fe: 6767 disas_insn_new(s, cpu, b); 6768 break; 6769 default: 6770 goto unknown_op; 6771 } 6772 return true; 6773 illegal_op: 6774 gen_illegal_opcode(s); 6775 return true; 6776 unknown_op: 6777 gen_unknown_opcode(env, s); 6778 return true; 6779 } 6780 6781 void tcg_x86_init(void) 6782 { 6783 static const char reg_names[CPU_NB_REGS][4] = { 6784 #ifdef TARGET_X86_64 6785 [R_EAX] = "rax", 6786 [R_EBX] = "rbx", 6787 [R_ECX] = "rcx", 6788 [R_EDX] = "rdx", 6789 [R_ESI] = "rsi", 6790 [R_EDI] = "rdi", 6791 [R_EBP] = "rbp", 6792 [R_ESP] = "rsp", 6793 [8] = "r8", 6794 [9] = "r9", 6795 [10] = "r10", 6796 [11] = "r11", 6797 [12] = "r12", 6798 [13] = "r13", 6799 [14] = "r14", 6800 [15] = "r15", 6801 #else 6802 [R_EAX] = "eax", 6803 [R_EBX] = "ebx", 6804 [R_ECX] = "ecx", 6805 [R_EDX] = "edx", 6806 [R_ESI] = "esi", 6807 [R_EDI] = "edi", 6808 [R_EBP] = "ebp", 6809 [R_ESP] = "esp", 6810 #endif 6811 }; 6812 static const char eip_name[] = { 6813 #ifdef TARGET_X86_64 6814 "rip" 6815 #else 6816 "eip" 6817 #endif 6818 }; 6819 static const char seg_base_names[6][8] = { 6820 [R_CS] = "cs_base", 6821 [R_DS] = "ds_base", 6822 [R_ES] = "es_base", 6823 [R_FS] = "fs_base", 6824 [R_GS] = "gs_base", 6825 [R_SS] = "ss_base", 6826 }; 6827 static const char bnd_regl_names[4][8] = { 6828 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb" 6829 }; 6830 static const char bnd_regu_names[4][8] = { 6831 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" 6832 }; 6833 int i; 6834 6835 cpu_cc_op = tcg_global_mem_new_i32(cpu_env, 6836 offsetof(CPUX86State, cc_op), "cc_op"); 6837 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst), 6838 "cc_dst"); 6839 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src), 6840 "cc_src"); 6841 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2), 6842 "cc_src2"); 6843 cpu_eip = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, eip), eip_name); 6844 6845 for (i = 0; i < CPU_NB_REGS; ++i) { 6846 cpu_regs[i] = tcg_global_mem_new(cpu_env, 6847 offsetof(CPUX86State, regs[i]), 6848 reg_names[i]); 6849 } 6850 6851 for (i = 0; i < 6; ++i) { 6852 cpu_seg_base[i] 6853 = tcg_global_mem_new(cpu_env, 6854 offsetof(CPUX86State, segs[i].base), 6855 seg_base_names[i]); 6856 } 6857 6858 for (i = 0; i < 4; ++i) { 6859 cpu_bndl[i] 6860 = tcg_global_mem_new_i64(cpu_env, 6861 offsetof(CPUX86State, bnd_regs[i].lb), 6862 bnd_regl_names[i]); 6863 cpu_bndu[i] 6864 = tcg_global_mem_new_i64(cpu_env, 6865 offsetof(CPUX86State, bnd_regs[i].ub), 6866 bnd_regu_names[i]); 6867 } 6868 } 6869 6870 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 6871 { 6872 DisasContext *dc = container_of(dcbase, DisasContext, base); 6873 CPUX86State *env = cpu->env_ptr; 6874 uint32_t flags = dc->base.tb->flags; 6875 uint32_t cflags = tb_cflags(dc->base.tb); 6876 int cpl = (flags >> HF_CPL_SHIFT) & 3; 6877 int iopl = (flags >> IOPL_SHIFT) & 3; 6878 6879 dc->cs_base = dc->base.tb->cs_base; 6880 dc->pc_save = dc->base.pc_next; 6881 dc->flags = flags; 6882 #ifndef CONFIG_USER_ONLY 6883 dc->cpl = cpl; 6884 dc->iopl = iopl; 6885 #endif 6886 6887 /* We make some simplifying assumptions; validate they're correct. */ 6888 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); 6889 g_assert(CPL(dc) == cpl); 6890 g_assert(IOPL(dc) == iopl); 6891 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0)); 6892 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0)); 6893 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0)); 6894 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0)); 6895 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0)); 6896 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0)); 6897 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0)); 6898 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0)); 6899 6900 dc->cc_op = CC_OP_DYNAMIC; 6901 dc->cc_op_dirty = false; 6902 dc->popl_esp_hack = 0; 6903 /* select memory access functions */ 6904 dc->mem_index = 0; 6905 #ifdef CONFIG_SOFTMMU 6906 dc->mem_index = cpu_mmu_index(env, false); 6907 #endif 6908 dc->cpuid_features = env->features[FEAT_1_EDX]; 6909 dc->cpuid_ext_features = env->features[FEAT_1_ECX]; 6910 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; 6911 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; 6912 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; 6913 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX]; 6914 dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; 6915 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || 6916 (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 6917 /* 6918 * If jmp_opt, we want to handle each string instruction individually. 6919 * For icount also disable repz optimization so that each iteration 6920 * is accounted separately. 6921 */ 6922 dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT); 6923 6924 dc->T0 = tcg_temp_new(); 6925 dc->T1 = tcg_temp_new(); 6926 dc->A0 = tcg_temp_new(); 6927 6928 dc->tmp0 = tcg_temp_new(); 6929 dc->tmp1_i64 = tcg_temp_new_i64(); 6930 dc->tmp2_i32 = tcg_temp_new_i32(); 6931 dc->tmp3_i32 = tcg_temp_new_i32(); 6932 dc->tmp4 = tcg_temp_new(); 6933 dc->cc_srcT = tcg_temp_local_new(); 6934 } 6935 6936 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) 6937 { 6938 } 6939 6940 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 6941 { 6942 DisasContext *dc = container_of(dcbase, DisasContext, base); 6943 target_ulong pc_arg = dc->base.pc_next; 6944 6945 dc->prev_insn_end = tcg_last_op(); 6946 if (TARGET_TB_PCREL) { 6947 pc_arg -= dc->cs_base; 6948 pc_arg &= ~TARGET_PAGE_MASK; 6949 } 6950 tcg_gen_insn_start(pc_arg, dc->cc_op); 6951 } 6952 6953 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 6954 { 6955 DisasContext *dc = container_of(dcbase, DisasContext, base); 6956 6957 #ifdef TARGET_VSYSCALL_PAGE 6958 /* 6959 * Detect entry into the vsyscall page and invoke the syscall. 6960 */ 6961 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) { 6962 gen_exception(dc, EXCP_VSYSCALL); 6963 dc->base.pc_next = dc->pc + 1; 6964 return; 6965 } 6966 #endif 6967 6968 if (disas_insn(dc, cpu)) { 6969 target_ulong pc_next = dc->pc; 6970 dc->base.pc_next = pc_next; 6971 6972 if (dc->base.is_jmp == DISAS_NEXT) { 6973 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) { 6974 /* 6975 * If single step mode, we generate only one instruction and 6976 * generate an exception. 6977 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 6978 * the flag and abort the translation to give the irqs a 6979 * chance to happen. 6980 */ 6981 dc->base.is_jmp = DISAS_EOB_NEXT; 6982 } else if (!is_same_page(&dc->base, pc_next)) { 6983 dc->base.is_jmp = DISAS_TOO_MANY; 6984 } 6985 } 6986 } 6987 } 6988 6989 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 6990 { 6991 DisasContext *dc = container_of(dcbase, DisasContext, base); 6992 6993 switch (dc->base.is_jmp) { 6994 case DISAS_NORETURN: 6995 break; 6996 case DISAS_TOO_MANY: 6997 gen_update_cc_op(dc); 6998 gen_jmp_rel_csize(dc, 0, 0); 6999 break; 7000 case DISAS_EOB_NEXT: 7001 gen_update_cc_op(dc); 7002 gen_update_eip_cur(dc); 7003 /* fall through */ 7004 case DISAS_EOB_ONLY: 7005 gen_eob(dc); 7006 break; 7007 case DISAS_EOB_INHIBIT_IRQ: 7008 gen_update_cc_op(dc); 7009 gen_update_eip_cur(dc); 7010 gen_eob_inhibit_irq(dc, true); 7011 break; 7012 case DISAS_JUMP: 7013 gen_jr(dc); 7014 break; 7015 default: 7016 g_assert_not_reached(); 7017 } 7018 } 7019 7020 static void i386_tr_disas_log(const DisasContextBase *dcbase, 7021 CPUState *cpu, FILE *logfile) 7022 { 7023 DisasContext *dc = container_of(dcbase, DisasContext, base); 7024 7025 fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first)); 7026 target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size); 7027 } 7028 7029 static const TranslatorOps i386_tr_ops = { 7030 .init_disas_context = i386_tr_init_disas_context, 7031 .tb_start = i386_tr_tb_start, 7032 .insn_start = i386_tr_insn_start, 7033 .translate_insn = i386_tr_translate_insn, 7034 .tb_stop = i386_tr_tb_stop, 7035 .disas_log = i386_tr_disas_log, 7036 }; 7037 7038 /* generate intermediate code for basic block 'tb'. */ 7039 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns, 7040 target_ulong pc, void *host_pc) 7041 { 7042 DisasContext dc; 7043 7044 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); 7045 } 7046