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