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