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