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