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