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 "exec/exec-all.h" 24 #include "tcg/tcg-op.h" 25 #include "tcg/tcg-op-gvec.h" 26 #include "exec/translator.h" 27 #include "fpu/softfloat.h" 28 29 #include "exec/helper-proto.h" 30 #include "exec/helper-gen.h" 31 #include "helper-tcg.h" 32 33 #include "exec/log.h" 34 35 #define HELPER_H "helper.h" 36 #include "exec/helper-info.c.inc" 37 #undef HELPER_H 38 39 /* Fixes for Windows namespace pollution. */ 40 #undef IN 41 #undef OUT 42 43 #define PREFIX_REPZ 0x01 44 #define PREFIX_REPNZ 0x02 45 #define PREFIX_LOCK 0x04 46 #define PREFIX_DATA 0x08 47 #define PREFIX_ADR 0x10 48 #define PREFIX_VEX 0x20 49 #define PREFIX_REX 0x40 50 51 #ifdef TARGET_X86_64 52 # define ctztl ctz64 53 # define clztl clz64 54 #else 55 # define ctztl ctz32 56 # define clztl clz32 57 #endif 58 59 /* For a switch indexed by MODRM, match all memory operands for a given OP. */ 60 #define CASE_MODRM_MEM_OP(OP) \ 61 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 62 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 63 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7 64 65 #define CASE_MODRM_OP(OP) \ 66 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \ 67 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \ 68 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \ 69 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7 70 71 //#define MACRO_TEST 1 72 73 /* global register indexes */ 74 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2; 75 static TCGv cpu_eip; 76 static TCGv_i32 cpu_cc_op; 77 static TCGv cpu_regs[CPU_NB_REGS]; 78 static TCGv cpu_seg_base[6]; 79 static TCGv_i64 cpu_bndl[4]; 80 static TCGv_i64 cpu_bndu[4]; 81 82 typedef struct DisasContext { 83 DisasContextBase base; 84 85 target_ulong pc; /* pc = eip + cs_base */ 86 target_ulong cs_base; /* base of CS segment */ 87 target_ulong pc_save; 88 89 MemOp aflag; 90 MemOp dflag; 91 92 int8_t override; /* -1 if no override, else R_CS, R_DS, etc */ 93 uint8_t prefix; 94 95 bool has_modrm; 96 uint8_t modrm; 97 98 #ifndef CONFIG_USER_ONLY 99 uint8_t cpl; /* code priv level */ 100 uint8_t iopl; /* i/o priv level */ 101 #endif 102 uint8_t vex_l; /* vex vector length */ 103 uint8_t vex_v; /* vex vvvv register, without 1's complement. */ 104 uint8_t popl_esp_hack; /* for correct popl with esp base handling */ 105 uint8_t rip_offset; /* only used in x86_64, but left for simplicity */ 106 107 #ifdef TARGET_X86_64 108 uint8_t rex_r; 109 uint8_t rex_x; 110 uint8_t rex_b; 111 #endif 112 bool vex_w; /* used by AVX even on 32-bit processors */ 113 bool jmp_opt; /* use direct block chaining for direct jumps */ 114 bool repz_opt; /* optimize jumps within repz instructions */ 115 bool cc_op_dirty; 116 117 CCOp cc_op; /* current CC operation */ 118 int mem_index; /* select memory access functions */ 119 uint32_t flags; /* all execution flags */ 120 int cpuid_features; 121 int cpuid_ext_features; 122 int cpuid_ext2_features; 123 int cpuid_ext3_features; 124 int cpuid_7_0_ebx_features; 125 int cpuid_7_0_ecx_features; 126 int cpuid_7_1_eax_features; 127 int cpuid_xsave_features; 128 129 /* TCG local temps */ 130 TCGv cc_srcT; 131 TCGv A0; 132 TCGv T0; 133 TCGv T1; 134 135 /* TCG local register indexes (only used inside old micro ops) */ 136 TCGv tmp0; 137 TCGv tmp4; 138 TCGv_i32 tmp2_i32; 139 TCGv_i32 tmp3_i32; 140 TCGv_i64 tmp1_i64; 141 142 sigjmp_buf jmpbuf; 143 TCGOp *prev_insn_start; 144 TCGOp *prev_insn_end; 145 } DisasContext; 146 147 /* 148 * Point EIP to next instruction before ending translation. 149 * For instructions that can change hflags. 150 */ 151 #define DISAS_EOB_NEXT DISAS_TARGET_0 152 153 /* 154 * Point EIP to next instruction and set HF_INHIBIT_IRQ if not 155 * already set. For instructions that activate interrupt shadow. 156 */ 157 #define DISAS_EOB_INHIBIT_IRQ DISAS_TARGET_1 158 159 /* 160 * Return to the main loop; EIP might have already been updated 161 * but even in that case do not use lookup_and_goto_ptr(). 162 */ 163 #define DISAS_EOB_ONLY DISAS_TARGET_2 164 165 /* 166 * EIP has already been updated. For jumps that wish to use 167 * lookup_and_goto_ptr() 168 */ 169 #define DISAS_JUMP DISAS_TARGET_3 170 171 /* 172 * EIP has already been updated. Use updated value of 173 * EFLAGS.TF to determine singlestep trap (SYSCALL/SYSRET). 174 */ 175 #define DISAS_EOB_RECHECK_TF DISAS_TARGET_4 176 177 /* The environment in which user-only runs is constrained. */ 178 #ifdef CONFIG_USER_ONLY 179 #define PE(S) true 180 #define CPL(S) 3 181 #define IOPL(S) 0 182 #define SVME(S) false 183 #define GUEST(S) false 184 #else 185 #define PE(S) (((S)->flags & HF_PE_MASK) != 0) 186 #define CPL(S) ((S)->cpl) 187 #define IOPL(S) ((S)->iopl) 188 #define SVME(S) (((S)->flags & HF_SVME_MASK) != 0) 189 #define GUEST(S) (((S)->flags & HF_GUEST_MASK) != 0) 190 #endif 191 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64) 192 #define VM86(S) false 193 #define CODE32(S) true 194 #define SS32(S) true 195 #define ADDSEG(S) false 196 #else 197 #define VM86(S) (((S)->flags & HF_VM_MASK) != 0) 198 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0) 199 #define SS32(S) (((S)->flags & HF_SS32_MASK) != 0) 200 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0) 201 #endif 202 #if !defined(TARGET_X86_64) 203 #define CODE64(S) false 204 #elif defined(CONFIG_USER_ONLY) 205 #define CODE64(S) true 206 #else 207 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0) 208 #endif 209 #if defined(CONFIG_USER_ONLY) || defined(TARGET_X86_64) 210 #define LMA(S) (((S)->flags & HF_LMA_MASK) != 0) 211 #else 212 #define LMA(S) false 213 #endif 214 215 #ifdef TARGET_X86_64 216 #define REX_PREFIX(S) (((S)->prefix & PREFIX_REX) != 0) 217 #define REX_W(S) ((S)->vex_w) 218 #define REX_R(S) ((S)->rex_r + 0) 219 #define REX_X(S) ((S)->rex_x + 0) 220 #define REX_B(S) ((S)->rex_b + 0) 221 #else 222 #define REX_PREFIX(S) false 223 #define REX_W(S) false 224 #define REX_R(S) 0 225 #define REX_X(S) 0 226 #define REX_B(S) 0 227 #endif 228 229 /* 230 * Many sysemu-only helpers are not reachable for user-only. 231 * Define stub generators here, so that we need not either sprinkle 232 * ifdefs through the translator, nor provide the helper function. 233 */ 234 #define STUB_HELPER(NAME, ...) \ 235 static inline void gen_helper_##NAME(__VA_ARGS__) \ 236 { qemu_build_not_reached(); } 237 238 #ifdef CONFIG_USER_ONLY 239 STUB_HELPER(clgi, TCGv_env env) 240 STUB_HELPER(flush_page, TCGv_env env, TCGv addr) 241 STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port) 242 STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port) 243 STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port) 244 STUB_HELPER(monitor, TCGv_env env, TCGv addr) 245 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs) 246 STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 247 STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 248 STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val) 249 STUB_HELPER(stgi, TCGv_env env) 250 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type) 251 STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag) 252 STUB_HELPER(vmmcall, TCGv_env env) 253 STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs) 254 STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag) 255 STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val) 256 #endif 257 258 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num); 259 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num); 260 static void gen_exception_gpf(DisasContext *s); 261 262 /* i386 shift ops */ 263 enum { 264 OP_ROL, 265 OP_ROR, 266 OP_RCL, 267 OP_RCR, 268 OP_SHL, 269 OP_SHR, 270 OP_SHL1, /* undocumented */ 271 OP_SAR = 7, 272 }; 273 274 enum { 275 JCC_O, 276 JCC_B, 277 JCC_Z, 278 JCC_BE, 279 JCC_S, 280 JCC_P, 281 JCC_L, 282 JCC_LE, 283 }; 284 285 enum { 286 USES_CC_DST = 1, 287 USES_CC_SRC = 2, 288 USES_CC_SRC2 = 4, 289 USES_CC_SRCT = 8, 290 }; 291 292 /* Bit set if the global variable is live after setting CC_OP to X. */ 293 static const uint8_t cc_op_live[CC_OP_NB] = { 294 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 295 [CC_OP_EFLAGS] = USES_CC_SRC, 296 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC, 297 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC, 298 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 299 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT, 300 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 301 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST, 302 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC, 303 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC, 304 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC, 305 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC, 306 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC, 307 [CC_OP_BLSIB ... CC_OP_BLSIQ] = USES_CC_DST | USES_CC_SRC, 308 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC, 309 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2, 310 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, 311 [CC_OP_CLR] = 0, 312 [CC_OP_POPCNT] = USES_CC_DST, 313 }; 314 315 static void set_cc_op_1(DisasContext *s, CCOp op, bool dirty) 316 { 317 int dead; 318 319 if (s->cc_op == op) { 320 return; 321 } 322 323 /* Discard CC computation that will no longer be used. */ 324 dead = cc_op_live[s->cc_op] & ~cc_op_live[op]; 325 if (dead & USES_CC_DST) { 326 tcg_gen_discard_tl(cpu_cc_dst); 327 } 328 if (dead & USES_CC_SRC) { 329 tcg_gen_discard_tl(cpu_cc_src); 330 } 331 if (dead & USES_CC_SRC2) { 332 tcg_gen_discard_tl(cpu_cc_src2); 333 } 334 if (dead & USES_CC_SRCT) { 335 tcg_gen_discard_tl(s->cc_srcT); 336 } 337 338 if (dirty && s->cc_op == CC_OP_DYNAMIC) { 339 tcg_gen_discard_i32(cpu_cc_op); 340 } 341 s->cc_op_dirty = dirty; 342 s->cc_op = op; 343 } 344 345 static void set_cc_op(DisasContext *s, CCOp op) 346 { 347 /* 348 * The DYNAMIC setting is translator only, everything else 349 * will be spilled later. 350 */ 351 set_cc_op_1(s, op, op != CC_OP_DYNAMIC); 352 } 353 354 static void assume_cc_op(DisasContext *s, CCOp op) 355 { 356 set_cc_op_1(s, op, false); 357 } 358 359 static void gen_update_cc_op(DisasContext *s) 360 { 361 if (s->cc_op_dirty) { 362 tcg_gen_movi_i32(cpu_cc_op, s->cc_op); 363 s->cc_op_dirty = false; 364 } 365 } 366 367 #ifdef TARGET_X86_64 368 369 #define NB_OP_SIZES 4 370 371 #else /* !TARGET_X86_64 */ 372 373 #define NB_OP_SIZES 3 374 375 #endif /* !TARGET_X86_64 */ 376 377 #if HOST_BIG_ENDIAN 378 #define REG_B_OFFSET (sizeof(target_ulong) - 1) 379 #define REG_H_OFFSET (sizeof(target_ulong) - 2) 380 #define REG_W_OFFSET (sizeof(target_ulong) - 2) 381 #define REG_L_OFFSET (sizeof(target_ulong) - 4) 382 #define REG_LH_OFFSET (sizeof(target_ulong) - 8) 383 #else 384 #define REG_B_OFFSET 0 385 #define REG_H_OFFSET 1 386 #define REG_W_OFFSET 0 387 #define REG_L_OFFSET 0 388 #define REG_LH_OFFSET 4 389 #endif 390 391 /* In instruction encodings for byte register accesses the 392 * register number usually indicates "low 8 bits of register N"; 393 * however there are some special cases where N 4..7 indicates 394 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return 395 * true for this special case, false otherwise. 396 */ 397 static inline bool byte_reg_is_xH(DisasContext *s, int reg) 398 { 399 /* Any time the REX prefix is present, byte registers are uniform */ 400 if (reg < 4 || REX_PREFIX(s)) { 401 return false; 402 } 403 return true; 404 } 405 406 /* Select the size of a push/pop operation. */ 407 static inline MemOp mo_pushpop(DisasContext *s, MemOp ot) 408 { 409 if (CODE64(s)) { 410 return ot == MO_16 ? MO_16 : MO_64; 411 } else { 412 return ot; 413 } 414 } 415 416 /* Select the size of the stack pointer. */ 417 static inline MemOp mo_stacksize(DisasContext *s) 418 { 419 return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16; 420 } 421 422 /* Compute the result of writing t0 to the OT-sized register REG. 423 * 424 * If DEST is NULL, store the result into the register and return the 425 * register's TCGv. 426 * 427 * If DEST is not NULL, store the result into DEST and return the 428 * register's TCGv. 429 */ 430 static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest, TCGv t0) 431 { 432 switch(ot) { 433 case MO_8: 434 if (byte_reg_is_xH(s, reg)) { 435 dest = dest ? dest : cpu_regs[reg - 4]; 436 tcg_gen_deposit_tl(dest, cpu_regs[reg - 4], t0, 8, 8); 437 return cpu_regs[reg - 4]; 438 } 439 dest = dest ? dest : cpu_regs[reg]; 440 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 8); 441 break; 442 case MO_16: 443 dest = dest ? dest : cpu_regs[reg]; 444 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 16); 445 break; 446 case MO_32: 447 /* For x86_64, this sets the higher half of register to zero. 448 For i386, this is equivalent to a mov. */ 449 dest = dest ? dest : cpu_regs[reg]; 450 tcg_gen_ext32u_tl(dest, t0); 451 break; 452 #ifdef TARGET_X86_64 453 case MO_64: 454 dest = dest ? dest : cpu_regs[reg]; 455 tcg_gen_mov_tl(dest, t0); 456 break; 457 #endif 458 default: 459 g_assert_not_reached(); 460 } 461 return cpu_regs[reg]; 462 } 463 464 static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0) 465 { 466 gen_op_deposit_reg_v(s, ot, reg, NULL, t0); 467 } 468 469 static inline 470 void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg) 471 { 472 if (ot == MO_8 && byte_reg_is_xH(s, reg)) { 473 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8); 474 } else { 475 tcg_gen_mov_tl(t0, cpu_regs[reg]); 476 } 477 } 478 479 static void gen_add_A0_im(DisasContext *s, int val) 480 { 481 tcg_gen_addi_tl(s->A0, s->A0, val); 482 if (!CODE64(s)) { 483 tcg_gen_ext32u_tl(s->A0, s->A0); 484 } 485 } 486 487 static inline void gen_op_jmp_v(DisasContext *s, TCGv dest) 488 { 489 tcg_gen_mov_tl(cpu_eip, dest); 490 s->pc_save = -1; 491 } 492 493 static inline 494 void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val) 495 { 496 tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val); 497 gen_op_mov_reg_v(s, size, reg, s->tmp0); 498 } 499 500 static inline void gen_op_add_reg(DisasContext *s, MemOp size, int reg, TCGv val) 501 { 502 tcg_gen_add_tl(s->tmp0, cpu_regs[reg], val); 503 gen_op_mov_reg_v(s, size, reg, s->tmp0); 504 } 505 506 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 507 { 508 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE); 509 } 510 511 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0) 512 { 513 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE); 514 } 515 516 static void gen_update_eip_next(DisasContext *s) 517 { 518 assert(s->pc_save != -1); 519 if (tb_cflags(s->base.tb) & CF_PCREL) { 520 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save); 521 } else if (CODE64(s)) { 522 tcg_gen_movi_tl(cpu_eip, s->pc); 523 } else { 524 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->pc - s->cs_base)); 525 } 526 s->pc_save = s->pc; 527 } 528 529 static void gen_update_eip_cur(DisasContext *s) 530 { 531 assert(s->pc_save != -1); 532 if (tb_cflags(s->base.tb) & CF_PCREL) { 533 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save); 534 } else if (CODE64(s)) { 535 tcg_gen_movi_tl(cpu_eip, s->base.pc_next); 536 } else { 537 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->base.pc_next - s->cs_base)); 538 } 539 s->pc_save = s->base.pc_next; 540 } 541 542 static int cur_insn_len(DisasContext *s) 543 { 544 return s->pc - s->base.pc_next; 545 } 546 547 static TCGv_i32 cur_insn_len_i32(DisasContext *s) 548 { 549 return tcg_constant_i32(cur_insn_len(s)); 550 } 551 552 static TCGv_i32 eip_next_i32(DisasContext *s) 553 { 554 assert(s->pc_save != -1); 555 /* 556 * This function has two users: lcall_real (always 16-bit mode), and 557 * iret_protected (16, 32, or 64-bit mode). IRET only uses the value 558 * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is 559 * why passing a 32-bit value isn't broken. To avoid using this where 560 * we shouldn't, return -1 in 64-bit mode so that execution goes into 561 * the weeds quickly. 562 */ 563 if (CODE64(s)) { 564 return tcg_constant_i32(-1); 565 } 566 if (tb_cflags(s->base.tb) & CF_PCREL) { 567 TCGv_i32 ret = tcg_temp_new_i32(); 568 tcg_gen_trunc_tl_i32(ret, cpu_eip); 569 tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save); 570 return ret; 571 } else { 572 return tcg_constant_i32(s->pc - s->cs_base); 573 } 574 } 575 576 static TCGv eip_next_tl(DisasContext *s) 577 { 578 assert(s->pc_save != -1); 579 if (tb_cflags(s->base.tb) & CF_PCREL) { 580 TCGv ret = tcg_temp_new(); 581 tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save); 582 return ret; 583 } else if (CODE64(s)) { 584 return tcg_constant_tl(s->pc); 585 } else { 586 return tcg_constant_tl((uint32_t)(s->pc - s->cs_base)); 587 } 588 } 589 590 static TCGv eip_cur_tl(DisasContext *s) 591 { 592 assert(s->pc_save != -1); 593 if (tb_cflags(s->base.tb) & CF_PCREL) { 594 TCGv ret = tcg_temp_new(); 595 tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save); 596 return ret; 597 } else if (CODE64(s)) { 598 return tcg_constant_tl(s->base.pc_next); 599 } else { 600 return tcg_constant_tl((uint32_t)(s->base.pc_next - s->cs_base)); 601 } 602 } 603 604 /* Compute SEG:REG into DEST. SEG is selected from the override segment 605 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to 606 indicate no override. */ 607 static void gen_lea_v_seg_dest(DisasContext *s, MemOp aflag, TCGv dest, TCGv a0, 608 int def_seg, int ovr_seg) 609 { 610 switch (aflag) { 611 #ifdef TARGET_X86_64 612 case MO_64: 613 if (ovr_seg < 0) { 614 tcg_gen_mov_tl(dest, a0); 615 return; 616 } 617 break; 618 #endif 619 case MO_32: 620 /* 32 bit address */ 621 if (ovr_seg < 0 && ADDSEG(s)) { 622 ovr_seg = def_seg; 623 } 624 if (ovr_seg < 0) { 625 tcg_gen_ext32u_tl(dest, a0); 626 return; 627 } 628 break; 629 case MO_16: 630 /* 16 bit address */ 631 tcg_gen_ext16u_tl(dest, a0); 632 a0 = dest; 633 if (ovr_seg < 0) { 634 if (ADDSEG(s)) { 635 ovr_seg = def_seg; 636 } else { 637 return; 638 } 639 } 640 break; 641 default: 642 g_assert_not_reached(); 643 } 644 645 if (ovr_seg >= 0) { 646 TCGv seg = cpu_seg_base[ovr_seg]; 647 648 if (aflag == MO_64) { 649 tcg_gen_add_tl(dest, a0, seg); 650 } else if (CODE64(s)) { 651 tcg_gen_ext32u_tl(dest, a0); 652 tcg_gen_add_tl(dest, dest, seg); 653 } else { 654 tcg_gen_add_tl(dest, a0, seg); 655 tcg_gen_ext32u_tl(dest, dest); 656 } 657 } 658 } 659 660 static void gen_lea_v_seg(DisasContext *s, TCGv a0, 661 int def_seg, int ovr_seg) 662 { 663 gen_lea_v_seg_dest(s, s->aflag, s->A0, a0, def_seg, ovr_seg); 664 } 665 666 static inline void gen_string_movl_A0_ESI(DisasContext *s) 667 { 668 gen_lea_v_seg(s, cpu_regs[R_ESI], R_DS, s->override); 669 } 670 671 static inline void gen_string_movl_A0_EDI(DisasContext *s) 672 { 673 gen_lea_v_seg(s, cpu_regs[R_EDI], R_ES, -1); 674 } 675 676 static inline TCGv gen_compute_Dshift(DisasContext *s, MemOp ot) 677 { 678 TCGv dshift = tcg_temp_new(); 679 tcg_gen_ld32s_tl(dshift, tcg_env, offsetof(CPUX86State, df)); 680 tcg_gen_shli_tl(dshift, dshift, ot); 681 return dshift; 682 }; 683 684 static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign) 685 { 686 if (size == MO_TL) { 687 return src; 688 } 689 if (!dst) { 690 dst = tcg_temp_new(); 691 } 692 tcg_gen_ext_tl(dst, src, size | (sign ? MO_SIGN : 0)); 693 return dst; 694 } 695 696 static void gen_exts(MemOp ot, TCGv reg) 697 { 698 gen_ext_tl(reg, reg, ot, true); 699 } 700 701 static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1) 702 { 703 TCGv tmp = gen_ext_tl(NULL, cpu_regs[R_ECX], s->aflag, false); 704 705 tcg_gen_brcondi_tl(cond, tmp, 0, label1); 706 } 707 708 static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1) 709 { 710 gen_op_j_ecx(s, TCG_COND_EQ, label1); 711 } 712 713 static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1) 714 { 715 gen_op_j_ecx(s, TCG_COND_NE, label1); 716 } 717 718 static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n) 719 { 720 switch (ot) { 721 case MO_8: 722 gen_helper_inb(v, tcg_env, n); 723 break; 724 case MO_16: 725 gen_helper_inw(v, tcg_env, n); 726 break; 727 case MO_32: 728 gen_helper_inl(v, tcg_env, n); 729 break; 730 default: 731 g_assert_not_reached(); 732 } 733 } 734 735 static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n) 736 { 737 switch (ot) { 738 case MO_8: 739 gen_helper_outb(tcg_env, v, n); 740 break; 741 case MO_16: 742 gen_helper_outw(tcg_env, v, n); 743 break; 744 case MO_32: 745 gen_helper_outl(tcg_env, v, n); 746 break; 747 default: 748 g_assert_not_reached(); 749 } 750 } 751 752 /* 753 * Validate that access to [port, port + 1<<ot) is allowed. 754 * Raise #GP, or VMM exit if not. 755 */ 756 static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port, 757 uint32_t svm_flags) 758 { 759 #ifdef CONFIG_USER_ONLY 760 /* 761 * We do not implement the ioperm(2) syscall, so the TSS check 762 * will always fail. 763 */ 764 gen_exception_gpf(s); 765 return false; 766 #else 767 if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) { 768 gen_helper_check_io(tcg_env, port, tcg_constant_i32(1 << ot)); 769 } 770 if (GUEST(s)) { 771 gen_update_cc_op(s); 772 gen_update_eip_cur(s); 773 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) { 774 svm_flags |= SVM_IOIO_REP_MASK; 775 } 776 svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot); 777 gen_helper_svm_check_io(tcg_env, port, 778 tcg_constant_i32(svm_flags), 779 cur_insn_len_i32(s)); 780 } 781 return true; 782 #endif 783 } 784 785 static void gen_movs(DisasContext *s, MemOp ot) 786 { 787 TCGv dshift; 788 789 gen_string_movl_A0_ESI(s); 790 gen_op_ld_v(s, ot, s->T0, s->A0); 791 gen_string_movl_A0_EDI(s); 792 gen_op_st_v(s, ot, s->T0, s->A0); 793 794 dshift = gen_compute_Dshift(s, ot); 795 gen_op_add_reg(s, s->aflag, R_ESI, dshift); 796 gen_op_add_reg(s, s->aflag, R_EDI, dshift); 797 } 798 799 /* compute all eflags to reg */ 800 static void gen_mov_eflags(DisasContext *s, TCGv reg) 801 { 802 TCGv dst, src1, src2; 803 TCGv_i32 cc_op; 804 int live, dead; 805 806 if (s->cc_op == CC_OP_EFLAGS) { 807 tcg_gen_mov_tl(reg, cpu_cc_src); 808 return; 809 } 810 if (s->cc_op == CC_OP_CLR) { 811 tcg_gen_movi_tl(reg, CC_Z | CC_P); 812 return; 813 } 814 815 dst = cpu_cc_dst; 816 src1 = cpu_cc_src; 817 src2 = cpu_cc_src2; 818 819 /* Take care to not read values that are not live. */ 820 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT; 821 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2); 822 if (dead) { 823 TCGv zero = tcg_constant_tl(0); 824 if (dead & USES_CC_DST) { 825 dst = zero; 826 } 827 if (dead & USES_CC_SRC) { 828 src1 = zero; 829 } 830 if (dead & USES_CC_SRC2) { 831 src2 = zero; 832 } 833 } 834 835 if (s->cc_op != CC_OP_DYNAMIC) { 836 cc_op = tcg_constant_i32(s->cc_op); 837 } else { 838 cc_op = cpu_cc_op; 839 } 840 gen_helper_cc_compute_all(reg, dst, src1, src2, cc_op); 841 } 842 843 /* compute all eflags to cc_src */ 844 static void gen_compute_eflags(DisasContext *s) 845 { 846 gen_mov_eflags(s, cpu_cc_src); 847 set_cc_op(s, CC_OP_EFLAGS); 848 } 849 850 typedef struct CCPrepare { 851 TCGCond cond; 852 TCGv reg; 853 TCGv reg2; 854 target_ulong imm; 855 bool use_reg2; 856 bool no_setcond; 857 } CCPrepare; 858 859 static CCPrepare gen_prepare_sign_nz(TCGv src, MemOp size) 860 { 861 if (size == MO_TL) { 862 return (CCPrepare) { .cond = TCG_COND_LT, .reg = src }; 863 } else { 864 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = src, 865 .imm = 1ull << ((8 << size) - 1) }; 866 } 867 } 868 869 static CCPrepare gen_prepare_val_nz(TCGv src, MemOp size, bool eqz) 870 { 871 if (size == MO_TL) { 872 return (CCPrepare) { .cond = eqz ? TCG_COND_EQ : TCG_COND_NE, 873 .reg = src }; 874 } else { 875 return (CCPrepare) { .cond = eqz ? TCG_COND_TSTEQ : TCG_COND_TSTNE, 876 .imm = MAKE_64BIT_MASK(0, 8 << size), 877 .reg = src }; 878 } 879 } 880 881 /* compute eflags.C, trying to store it in reg if not NULL */ 882 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg) 883 { 884 MemOp size; 885 886 switch (s->cc_op) { 887 case CC_OP_SUBB ... CC_OP_SUBQ: 888 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */ 889 size = s->cc_op - CC_OP_SUBB; 890 gen_ext_tl(s->cc_srcT, s->cc_srcT, size, false); 891 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 892 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = s->cc_srcT, 893 .reg2 = cpu_cc_src, .use_reg2 = true }; 894 895 case CC_OP_ADDB ... CC_OP_ADDQ: 896 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */ 897 size = s->cc_op - CC_OP_ADDB; 898 gen_ext_tl(cpu_cc_dst, cpu_cc_dst, size, false); 899 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 900 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = cpu_cc_dst, 901 .reg2 = cpu_cc_src, .use_reg2 = true }; 902 903 case CC_OP_LOGICB ... CC_OP_LOGICQ: 904 case CC_OP_CLR: 905 case CC_OP_POPCNT: 906 return (CCPrepare) { .cond = TCG_COND_NEVER }; 907 908 case CC_OP_INCB ... CC_OP_INCQ: 909 case CC_OP_DECB ... CC_OP_DECQ: 910 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src, 911 .no_setcond = true }; 912 913 case CC_OP_SHLB ... CC_OP_SHLQ: 914 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */ 915 size = s->cc_op - CC_OP_SHLB; 916 return gen_prepare_sign_nz(cpu_cc_src, size); 917 918 case CC_OP_MULB ... CC_OP_MULQ: 919 return (CCPrepare) { .cond = TCG_COND_NE, 920 .reg = cpu_cc_src }; 921 922 case CC_OP_BMILGB ... CC_OP_BMILGQ: 923 size = s->cc_op - CC_OP_BMILGB; 924 return gen_prepare_val_nz(cpu_cc_src, size, true); 925 926 case CC_OP_BLSIB ... CC_OP_BLSIQ: 927 size = s->cc_op - CC_OP_BLSIB; 928 return gen_prepare_val_nz(cpu_cc_src, size, false); 929 930 case CC_OP_ADCX: 931 case CC_OP_ADCOX: 932 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst, 933 .no_setcond = true }; 934 935 case CC_OP_EFLAGS: 936 case CC_OP_SARB ... CC_OP_SARQ: 937 /* CC_SRC & 1 */ 938 return (CCPrepare) { .cond = TCG_COND_TSTNE, 939 .reg = cpu_cc_src, .imm = CC_C }; 940 941 default: 942 /* The need to compute only C from CC_OP_DYNAMIC is important 943 in efficiently implementing e.g. INC at the start of a TB. */ 944 gen_update_cc_op(s); 945 if (!reg) { 946 reg = tcg_temp_new(); 947 } 948 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src, 949 cpu_cc_src2, cpu_cc_op); 950 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg, 951 .no_setcond = true }; 952 } 953 } 954 955 /* compute eflags.P, trying to store it in reg if not NULL */ 956 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg) 957 { 958 gen_compute_eflags(s); 959 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 960 .imm = CC_P }; 961 } 962 963 /* compute eflags.S, trying to store it in reg if not NULL */ 964 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg) 965 { 966 switch (s->cc_op) { 967 case CC_OP_DYNAMIC: 968 gen_compute_eflags(s); 969 /* FALLTHRU */ 970 case CC_OP_EFLAGS: 971 case CC_OP_ADCX: 972 case CC_OP_ADOX: 973 case CC_OP_ADCOX: 974 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 975 .imm = CC_S }; 976 case CC_OP_CLR: 977 case CC_OP_POPCNT: 978 return (CCPrepare) { .cond = TCG_COND_NEVER }; 979 default: 980 { 981 MemOp size = (s->cc_op - CC_OP_ADDB) & 3; 982 return gen_prepare_sign_nz(cpu_cc_dst, size); 983 } 984 } 985 } 986 987 /* compute eflags.O, trying to store it in reg if not NULL */ 988 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg) 989 { 990 switch (s->cc_op) { 991 case CC_OP_ADOX: 992 case CC_OP_ADCOX: 993 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2, 994 .no_setcond = true }; 995 case CC_OP_CLR: 996 case CC_OP_POPCNT: 997 return (CCPrepare) { .cond = TCG_COND_NEVER }; 998 case CC_OP_MULB ... CC_OP_MULQ: 999 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src }; 1000 default: 1001 gen_compute_eflags(s); 1002 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1003 .imm = CC_O }; 1004 } 1005 } 1006 1007 /* compute eflags.Z, trying to store it in reg if not NULL */ 1008 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg) 1009 { 1010 switch (s->cc_op) { 1011 case CC_OP_DYNAMIC: 1012 gen_compute_eflags(s); 1013 /* FALLTHRU */ 1014 case CC_OP_EFLAGS: 1015 case CC_OP_ADCX: 1016 case CC_OP_ADOX: 1017 case CC_OP_ADCOX: 1018 return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1019 .imm = CC_Z }; 1020 case CC_OP_CLR: 1021 return (CCPrepare) { .cond = TCG_COND_ALWAYS }; 1022 default: 1023 { 1024 MemOp size = (s->cc_op - CC_OP_ADDB) & 3; 1025 return gen_prepare_val_nz(cpu_cc_dst, size, true); 1026 } 1027 } 1028 } 1029 1030 /* return how to compute jump opcode 'b'. 'reg' can be clobbered 1031 * if needed; it may be used for CCPrepare.reg if that will 1032 * provide more freedom in the translation of a subsequent setcond. */ 1033 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg) 1034 { 1035 int inv, jcc_op, cond; 1036 MemOp size; 1037 CCPrepare cc; 1038 1039 inv = b & 1; 1040 jcc_op = (b >> 1) & 7; 1041 1042 switch (s->cc_op) { 1043 case CC_OP_SUBB ... CC_OP_SUBQ: 1044 /* We optimize relational operators for the cmp/jcc case. */ 1045 size = s->cc_op - CC_OP_SUBB; 1046 switch (jcc_op) { 1047 case JCC_BE: 1048 gen_ext_tl(s->cc_srcT, s->cc_srcT, size, false); 1049 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, false); 1050 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->cc_srcT, 1051 .reg2 = cpu_cc_src, .use_reg2 = true }; 1052 break; 1053 case JCC_L: 1054 cond = TCG_COND_LT; 1055 goto fast_jcc_l; 1056 case JCC_LE: 1057 cond = TCG_COND_LE; 1058 fast_jcc_l: 1059 gen_ext_tl(s->cc_srcT, s->cc_srcT, size, true); 1060 gen_ext_tl(cpu_cc_src, cpu_cc_src, size, true); 1061 cc = (CCPrepare) { .cond = cond, .reg = s->cc_srcT, 1062 .reg2 = cpu_cc_src, .use_reg2 = true }; 1063 break; 1064 1065 default: 1066 goto slow_jcc; 1067 } 1068 break; 1069 1070 default: 1071 slow_jcc: 1072 /* This actually generates good code for JC, JZ and JS. */ 1073 switch (jcc_op) { 1074 case JCC_O: 1075 cc = gen_prepare_eflags_o(s, reg); 1076 break; 1077 case JCC_B: 1078 cc = gen_prepare_eflags_c(s, reg); 1079 break; 1080 case JCC_Z: 1081 cc = gen_prepare_eflags_z(s, reg); 1082 break; 1083 case JCC_BE: 1084 gen_compute_eflags(s); 1085 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src, 1086 .imm = CC_Z | CC_C }; 1087 break; 1088 case JCC_S: 1089 cc = gen_prepare_eflags_s(s, reg); 1090 break; 1091 case JCC_P: 1092 cc = gen_prepare_eflags_p(s, reg); 1093 break; 1094 case JCC_L: 1095 gen_compute_eflags(s); 1096 if (!reg || reg == cpu_cc_src) { 1097 reg = tcg_temp_new(); 1098 } 1099 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S); 1100 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg, 1101 .imm = CC_O }; 1102 break; 1103 default: 1104 case JCC_LE: 1105 gen_compute_eflags(s); 1106 if (!reg || reg == cpu_cc_src) { 1107 reg = tcg_temp_new(); 1108 } 1109 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S); 1110 cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg, 1111 .imm = CC_O | CC_Z }; 1112 break; 1113 } 1114 break; 1115 } 1116 1117 if (inv) { 1118 cc.cond = tcg_invert_cond(cc.cond); 1119 } 1120 return cc; 1121 } 1122 1123 static void gen_setcc1(DisasContext *s, int b, TCGv reg) 1124 { 1125 CCPrepare cc = gen_prepare_cc(s, b, reg); 1126 1127 if (cc.no_setcond) { 1128 if (cc.cond == TCG_COND_EQ) { 1129 tcg_gen_xori_tl(reg, cc.reg, 1); 1130 } else { 1131 tcg_gen_mov_tl(reg, cc.reg); 1132 } 1133 return; 1134 } 1135 1136 if (cc.use_reg2) { 1137 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2); 1138 } else { 1139 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm); 1140 } 1141 } 1142 1143 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg) 1144 { 1145 gen_setcc1(s, JCC_B << 1, reg); 1146 } 1147 1148 /* generate a conditional jump to label 'l1' according to jump opcode 1149 value 'b'. In the fast case, T0 is guaranteed not to be used. */ 1150 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1) 1151 { 1152 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1153 1154 if (cc.use_reg2) { 1155 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1156 } else { 1157 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1158 } 1159 } 1160 1161 /* Generate a conditional jump to label 'l1' according to jump opcode 1162 value 'b'. In the fast case, T0 is guaranteed not to be used. 1163 One or both of the branches will call gen_jmp_rel, so ensure 1164 cc_op is clean. */ 1165 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1) 1166 { 1167 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1168 1169 gen_update_cc_op(s); 1170 if (cc.use_reg2) { 1171 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1); 1172 } else { 1173 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1); 1174 } 1175 } 1176 1177 /* XXX: does not work with gdbstub "ice" single step - not a 1178 serious problem. The caller can jump to the returned label 1179 to stop the REP but, if the flags have changed, it has to call 1180 gen_update_cc_op before doing so. */ 1181 static TCGLabel *gen_jz_ecx_string(DisasContext *s) 1182 { 1183 TCGLabel *l1 = gen_new_label(); 1184 TCGLabel *l2 = gen_new_label(); 1185 1186 gen_update_cc_op(s); 1187 gen_op_jnz_ecx(s, l1); 1188 gen_set_label(l2); 1189 gen_jmp_rel_csize(s, 0, 1); 1190 gen_set_label(l1); 1191 return l2; 1192 } 1193 1194 static void gen_stos(DisasContext *s, MemOp ot) 1195 { 1196 gen_string_movl_A0_EDI(s); 1197 gen_op_st_v(s, ot, s->T0, s->A0); 1198 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot)); 1199 } 1200 1201 static void gen_lods(DisasContext *s, MemOp ot) 1202 { 1203 gen_string_movl_A0_ESI(s); 1204 gen_op_ld_v(s, ot, s->T0, s->A0); 1205 gen_op_mov_reg_v(s, ot, R_EAX, s->T0); 1206 gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot)); 1207 } 1208 1209 static void gen_scas(DisasContext *s, MemOp ot) 1210 { 1211 gen_string_movl_A0_EDI(s); 1212 gen_op_ld_v(s, ot, s->T1, s->A0); 1213 tcg_gen_mov_tl(cpu_cc_src, s->T1); 1214 tcg_gen_mov_tl(s->cc_srcT, s->T0); 1215 tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1); 1216 set_cc_op(s, CC_OP_SUBB + ot); 1217 1218 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot)); 1219 } 1220 1221 static void gen_cmps(DisasContext *s, MemOp ot) 1222 { 1223 TCGv dshift; 1224 1225 gen_string_movl_A0_EDI(s); 1226 gen_op_ld_v(s, ot, s->T1, s->A0); 1227 gen_string_movl_A0_ESI(s); 1228 gen_op_ld_v(s, ot, s->T0, s->A0); 1229 tcg_gen_mov_tl(cpu_cc_src, s->T1); 1230 tcg_gen_mov_tl(s->cc_srcT, s->T0); 1231 tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1); 1232 set_cc_op(s, CC_OP_SUBB + ot); 1233 1234 dshift = gen_compute_Dshift(s, ot); 1235 gen_op_add_reg(s, s->aflag, R_ESI, dshift); 1236 gen_op_add_reg(s, s->aflag, R_EDI, dshift); 1237 } 1238 1239 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot) 1240 { 1241 if (s->flags & HF_IOBPT_MASK) { 1242 #ifdef CONFIG_USER_ONLY 1243 /* user-mode cpu should not be in IOBPT mode */ 1244 g_assert_not_reached(); 1245 #else 1246 TCGv_i32 t_size = tcg_constant_i32(1 << ot); 1247 TCGv t_next = eip_next_tl(s); 1248 gen_helper_bpt_io(tcg_env, t_port, t_size, t_next); 1249 #endif /* CONFIG_USER_ONLY */ 1250 } 1251 } 1252 1253 static void gen_ins(DisasContext *s, MemOp ot) 1254 { 1255 gen_string_movl_A0_EDI(s); 1256 /* Note: we must do this dummy write first to be restartable in 1257 case of page fault. */ 1258 tcg_gen_movi_tl(s->T0, 0); 1259 gen_op_st_v(s, ot, s->T0, s->A0); 1260 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 1261 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); 1262 gen_helper_in_func(ot, s->T0, s->tmp2_i32); 1263 gen_op_st_v(s, ot, s->T0, s->A0); 1264 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot)); 1265 gen_bpt_io(s, s->tmp2_i32, ot); 1266 } 1267 1268 static void gen_outs(DisasContext *s, MemOp ot) 1269 { 1270 gen_string_movl_A0_ESI(s); 1271 gen_op_ld_v(s, ot, s->T0, s->A0); 1272 1273 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); 1274 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); 1275 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0); 1276 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); 1277 gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot)); 1278 gen_bpt_io(s, s->tmp2_i32, ot); 1279 } 1280 1281 /* Generate jumps to current or next instruction */ 1282 static void gen_repz(DisasContext *s, MemOp ot, 1283 void (*fn)(DisasContext *s, MemOp ot)) 1284 { 1285 TCGLabel *l2; 1286 l2 = gen_jz_ecx_string(s); 1287 fn(s, ot); 1288 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 1289 /* 1290 * A loop would cause two single step exceptions if ECX = 1 1291 * before rep string_insn 1292 */ 1293 if (s->repz_opt) { 1294 gen_op_jz_ecx(s, l2); 1295 } 1296 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1297 } 1298 1299 static void gen_repz_nz(DisasContext *s, MemOp ot, 1300 void (*fn)(DisasContext *s, MemOp ot)) 1301 { 1302 TCGLabel *l2; 1303 int nz = (s->prefix & PREFIX_REPNZ) ? 1 : 0; 1304 1305 l2 = gen_jz_ecx_string(s); 1306 fn(s, ot); 1307 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); 1308 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); 1309 if (s->repz_opt) { 1310 gen_op_jz_ecx(s, l2); 1311 } 1312 /* 1313 * Only one iteration is done at a time, so the translation 1314 * block ends unconditionally after this instruction and there 1315 * is no control flow junction - no need to set CC_OP_DYNAMIC. 1316 */ 1317 gen_jmp_rel_csize(s, -cur_insn_len(s), 0); 1318 } 1319 1320 static void gen_helper_fp_arith_ST0_FT0(int op) 1321 { 1322 switch (op) { 1323 case 0: 1324 gen_helper_fadd_ST0_FT0(tcg_env); 1325 break; 1326 case 1: 1327 gen_helper_fmul_ST0_FT0(tcg_env); 1328 break; 1329 case 2: 1330 gen_helper_fcom_ST0_FT0(tcg_env); 1331 break; 1332 case 3: 1333 gen_helper_fcom_ST0_FT0(tcg_env); 1334 break; 1335 case 4: 1336 gen_helper_fsub_ST0_FT0(tcg_env); 1337 break; 1338 case 5: 1339 gen_helper_fsubr_ST0_FT0(tcg_env); 1340 break; 1341 case 6: 1342 gen_helper_fdiv_ST0_FT0(tcg_env); 1343 break; 1344 case 7: 1345 gen_helper_fdivr_ST0_FT0(tcg_env); 1346 break; 1347 } 1348 } 1349 1350 /* NOTE the exception in "r" op ordering */ 1351 static void gen_helper_fp_arith_STN_ST0(int op, int opreg) 1352 { 1353 TCGv_i32 tmp = tcg_constant_i32(opreg); 1354 switch (op) { 1355 case 0: 1356 gen_helper_fadd_STN_ST0(tcg_env, tmp); 1357 break; 1358 case 1: 1359 gen_helper_fmul_STN_ST0(tcg_env, tmp); 1360 break; 1361 case 4: 1362 gen_helper_fsubr_STN_ST0(tcg_env, tmp); 1363 break; 1364 case 5: 1365 gen_helper_fsub_STN_ST0(tcg_env, tmp); 1366 break; 1367 case 6: 1368 gen_helper_fdivr_STN_ST0(tcg_env, tmp); 1369 break; 1370 case 7: 1371 gen_helper_fdiv_STN_ST0(tcg_env, tmp); 1372 break; 1373 } 1374 } 1375 1376 static void gen_exception(DisasContext *s, int trapno) 1377 { 1378 gen_update_cc_op(s); 1379 gen_update_eip_cur(s); 1380 gen_helper_raise_exception(tcg_env, tcg_constant_i32(trapno)); 1381 s->base.is_jmp = DISAS_NORETURN; 1382 } 1383 1384 /* Generate #UD for the current instruction. The assumption here is that 1385 the instruction is known, but it isn't allowed in the current cpu mode. */ 1386 static void gen_illegal_opcode(DisasContext *s) 1387 { 1388 gen_exception(s, EXCP06_ILLOP); 1389 } 1390 1391 /* Generate #GP for the current instruction. */ 1392 static void gen_exception_gpf(DisasContext *s) 1393 { 1394 gen_exception(s, EXCP0D_GPF); 1395 } 1396 1397 /* Check for cpl == 0; if not, raise #GP and return false. */ 1398 static bool check_cpl0(DisasContext *s) 1399 { 1400 if (CPL(s) == 0) { 1401 return true; 1402 } 1403 gen_exception_gpf(s); 1404 return false; 1405 } 1406 1407 /* XXX: add faster immediate case */ 1408 static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, 1409 bool is_right, TCGv count) 1410 { 1411 target_ulong mask = (ot == MO_64 ? 63 : 31); 1412 1413 switch (ot) { 1414 case MO_16: 1415 /* Note: we implement the Intel behaviour for shift count > 16. 1416 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A 1417 portion by constructing it as a 32-bit value. */ 1418 if (is_right) { 1419 tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16); 1420 tcg_gen_mov_tl(s->T1, s->T0); 1421 tcg_gen_mov_tl(s->T0, s->tmp0); 1422 } else { 1423 tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16); 1424 } 1425 /* 1426 * If TARGET_X86_64 defined then fall through into MO_32 case, 1427 * otherwise fall through default case. 1428 */ 1429 case MO_32: 1430 #ifdef TARGET_X86_64 1431 /* Concatenate the two 32-bit values and use a 64-bit shift. */ 1432 tcg_gen_subi_tl(s->tmp0, count, 1); 1433 if (is_right) { 1434 tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1); 1435 tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0); 1436 tcg_gen_shr_i64(s->T0, s->T0, count); 1437 } else { 1438 tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0); 1439 tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0); 1440 tcg_gen_shl_i64(s->T0, s->T0, count); 1441 tcg_gen_shri_i64(s->tmp0, s->tmp0, 32); 1442 tcg_gen_shri_i64(s->T0, s->T0, 32); 1443 } 1444 break; 1445 #endif 1446 default: 1447 tcg_gen_subi_tl(s->tmp0, count, 1); 1448 if (is_right) { 1449 tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0); 1450 1451 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1452 tcg_gen_shr_tl(s->T0, s->T0, count); 1453 tcg_gen_shl_tl(s->T1, s->T1, s->tmp4); 1454 } else { 1455 tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0); 1456 if (ot == MO_16) { 1457 /* Only needed if count > 16, for Intel behaviour. */ 1458 tcg_gen_subfi_tl(s->tmp4, 33, count); 1459 tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4); 1460 tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4); 1461 } 1462 1463 tcg_gen_subfi_tl(s->tmp4, mask + 1, count); 1464 tcg_gen_shl_tl(s->T0, s->T0, count); 1465 tcg_gen_shr_tl(s->T1, s->T1, s->tmp4); 1466 } 1467 tcg_gen_movi_tl(s->tmp4, 0); 1468 tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4, 1469 s->tmp4, s->T1); 1470 tcg_gen_or_tl(s->T0, s->T0, s->T1); 1471 break; 1472 } 1473 } 1474 1475 #define X86_MAX_INSN_LENGTH 15 1476 1477 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes) 1478 { 1479 uint64_t pc = s->pc; 1480 1481 /* This is a subsequent insn that crosses a page boundary. */ 1482 if (s->base.num_insns > 1 && 1483 !is_same_page(&s->base, s->pc + num_bytes - 1)) { 1484 siglongjmp(s->jmpbuf, 2); 1485 } 1486 1487 s->pc += num_bytes; 1488 if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) { 1489 /* If the instruction's 16th byte is on a different page than the 1st, a 1490 * page fault on the second page wins over the general protection fault 1491 * caused by the instruction being too long. 1492 * This can happen even if the operand is only one byte long! 1493 */ 1494 if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) { 1495 (void)translator_ldub(env, &s->base, 1496 (s->pc - 1) & TARGET_PAGE_MASK); 1497 } 1498 siglongjmp(s->jmpbuf, 1); 1499 } 1500 1501 return pc; 1502 } 1503 1504 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s) 1505 { 1506 return translator_ldub(env, &s->base, advance_pc(env, s, 1)); 1507 } 1508 1509 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s) 1510 { 1511 return translator_lduw(env, &s->base, advance_pc(env, s, 2)); 1512 } 1513 1514 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s) 1515 { 1516 return translator_ldl(env, &s->base, advance_pc(env, s, 4)); 1517 } 1518 1519 #ifdef TARGET_X86_64 1520 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s) 1521 { 1522 return translator_ldq(env, &s->base, advance_pc(env, s, 8)); 1523 } 1524 #endif 1525 1526 /* Decompose an address. */ 1527 1528 typedef struct AddressParts { 1529 int def_seg; 1530 int base; 1531 int index; 1532 int scale; 1533 target_long disp; 1534 } AddressParts; 1535 1536 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s, 1537 int modrm, bool is_vsib) 1538 { 1539 int def_seg, base, index, scale, mod, rm; 1540 target_long disp; 1541 bool havesib; 1542 1543 def_seg = R_DS; 1544 index = -1; 1545 scale = 0; 1546 disp = 0; 1547 1548 mod = (modrm >> 6) & 3; 1549 rm = modrm & 7; 1550 base = rm | REX_B(s); 1551 1552 if (mod == 3) { 1553 /* Normally filtered out earlier, but including this path 1554 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */ 1555 goto done; 1556 } 1557 1558 switch (s->aflag) { 1559 case MO_64: 1560 case MO_32: 1561 havesib = 0; 1562 if (rm == 4) { 1563 int code = x86_ldub_code(env, s); 1564 scale = (code >> 6) & 3; 1565 index = ((code >> 3) & 7) | REX_X(s); 1566 if (index == 4 && !is_vsib) { 1567 index = -1; /* no index */ 1568 } 1569 base = (code & 7) | REX_B(s); 1570 havesib = 1; 1571 } 1572 1573 switch (mod) { 1574 case 0: 1575 if ((base & 7) == 5) { 1576 base = -1; 1577 disp = (int32_t)x86_ldl_code(env, s); 1578 if (CODE64(s) && !havesib) { 1579 base = -2; 1580 disp += s->pc + s->rip_offset; 1581 } 1582 } 1583 break; 1584 case 1: 1585 disp = (int8_t)x86_ldub_code(env, s); 1586 break; 1587 default: 1588 case 2: 1589 disp = (int32_t)x86_ldl_code(env, s); 1590 break; 1591 } 1592 1593 /* For correct popl handling with esp. */ 1594 if (base == R_ESP && s->popl_esp_hack) { 1595 disp += s->popl_esp_hack; 1596 } 1597 if (base == R_EBP || base == R_ESP) { 1598 def_seg = R_SS; 1599 } 1600 break; 1601 1602 case MO_16: 1603 if (mod == 0) { 1604 if (rm == 6) { 1605 base = -1; 1606 disp = x86_lduw_code(env, s); 1607 break; 1608 } 1609 } else if (mod == 1) { 1610 disp = (int8_t)x86_ldub_code(env, s); 1611 } else { 1612 disp = (int16_t)x86_lduw_code(env, s); 1613 } 1614 1615 switch (rm) { 1616 case 0: 1617 base = R_EBX; 1618 index = R_ESI; 1619 break; 1620 case 1: 1621 base = R_EBX; 1622 index = R_EDI; 1623 break; 1624 case 2: 1625 base = R_EBP; 1626 index = R_ESI; 1627 def_seg = R_SS; 1628 break; 1629 case 3: 1630 base = R_EBP; 1631 index = R_EDI; 1632 def_seg = R_SS; 1633 break; 1634 case 4: 1635 base = R_ESI; 1636 break; 1637 case 5: 1638 base = R_EDI; 1639 break; 1640 case 6: 1641 base = R_EBP; 1642 def_seg = R_SS; 1643 break; 1644 default: 1645 case 7: 1646 base = R_EBX; 1647 break; 1648 } 1649 break; 1650 1651 default: 1652 g_assert_not_reached(); 1653 } 1654 1655 done: 1656 return (AddressParts){ def_seg, base, index, scale, disp }; 1657 } 1658 1659 /* Compute the address, with a minimum number of TCG ops. */ 1660 static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib) 1661 { 1662 TCGv ea = NULL; 1663 1664 if (a.index >= 0 && !is_vsib) { 1665 if (a.scale == 0) { 1666 ea = cpu_regs[a.index]; 1667 } else { 1668 tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale); 1669 ea = s->A0; 1670 } 1671 if (a.base >= 0) { 1672 tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]); 1673 ea = s->A0; 1674 } 1675 } else if (a.base >= 0) { 1676 ea = cpu_regs[a.base]; 1677 } 1678 if (!ea) { 1679 if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) { 1680 /* With cpu_eip ~= pc_save, the expression is pc-relative. */ 1681 tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save); 1682 } else { 1683 tcg_gen_movi_tl(s->A0, a.disp); 1684 } 1685 ea = s->A0; 1686 } else if (a.disp != 0) { 1687 tcg_gen_addi_tl(s->A0, ea, a.disp); 1688 ea = s->A0; 1689 } 1690 1691 return ea; 1692 } 1693 1694 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) 1695 { 1696 AddressParts a = gen_lea_modrm_0(env, s, modrm, false); 1697 TCGv ea = gen_lea_modrm_1(s, a, false); 1698 gen_lea_v_seg(s, ea, a.def_seg, s->override); 1699 } 1700 1701 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm) 1702 { 1703 (void)gen_lea_modrm_0(env, s, modrm, false); 1704 } 1705 1706 /* Used for BNDCL, BNDCU, BNDCN. */ 1707 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm, 1708 TCGCond cond, TCGv_i64 bndv) 1709 { 1710 AddressParts a = gen_lea_modrm_0(env, s, modrm, false); 1711 TCGv ea = gen_lea_modrm_1(s, a, false); 1712 1713 tcg_gen_extu_tl_i64(s->tmp1_i64, ea); 1714 if (!CODE64(s)) { 1715 tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64); 1716 } 1717 tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv); 1718 tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64); 1719 gen_helper_bndck(tcg_env, s->tmp2_i32); 1720 } 1721 1722 /* generate modrm load of memory or register. */ 1723 static void gen_ld_modrm(CPUX86State *env, DisasContext *s, int modrm, MemOp ot) 1724 { 1725 int mod, rm; 1726 1727 mod = (modrm >> 6) & 3; 1728 rm = (modrm & 7) | REX_B(s); 1729 if (mod == 3) { 1730 gen_op_mov_v_reg(s, ot, s->T0, rm); 1731 } else { 1732 gen_lea_modrm(env, s, modrm); 1733 gen_op_ld_v(s, ot, s->T0, s->A0); 1734 } 1735 } 1736 1737 /* generate modrm store of memory or register. */ 1738 static void gen_st_modrm(CPUX86State *env, DisasContext *s, int modrm, MemOp ot) 1739 { 1740 int mod, rm; 1741 1742 mod = (modrm >> 6) & 3; 1743 rm = (modrm & 7) | REX_B(s); 1744 if (mod == 3) { 1745 gen_op_mov_reg_v(s, ot, rm, s->T0); 1746 } else { 1747 gen_lea_modrm(env, s, modrm); 1748 gen_op_st_v(s, ot, s->T0, s->A0); 1749 } 1750 } 1751 1752 static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot) 1753 { 1754 target_ulong ret; 1755 1756 switch (ot) { 1757 case MO_8: 1758 ret = x86_ldub_code(env, s); 1759 break; 1760 case MO_16: 1761 ret = x86_lduw_code(env, s); 1762 break; 1763 case MO_32: 1764 ret = x86_ldl_code(env, s); 1765 break; 1766 #ifdef TARGET_X86_64 1767 case MO_64: 1768 ret = x86_ldq_code(env, s); 1769 break; 1770 #endif 1771 default: 1772 g_assert_not_reached(); 1773 } 1774 return ret; 1775 } 1776 1777 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot) 1778 { 1779 uint32_t ret; 1780 1781 switch (ot) { 1782 case MO_8: 1783 ret = x86_ldub_code(env, s); 1784 break; 1785 case MO_16: 1786 ret = x86_lduw_code(env, s); 1787 break; 1788 case MO_32: 1789 #ifdef TARGET_X86_64 1790 case MO_64: 1791 #endif 1792 ret = x86_ldl_code(env, s); 1793 break; 1794 default: 1795 g_assert_not_reached(); 1796 } 1797 return ret; 1798 } 1799 1800 static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot) 1801 { 1802 target_long ret; 1803 1804 switch (ot) { 1805 case MO_8: 1806 ret = (int8_t) x86_ldub_code(env, s); 1807 break; 1808 case MO_16: 1809 ret = (int16_t) x86_lduw_code(env, s); 1810 break; 1811 case MO_32: 1812 ret = (int32_t) x86_ldl_code(env, s); 1813 break; 1814 #ifdef TARGET_X86_64 1815 case MO_64: 1816 ret = x86_ldq_code(env, s); 1817 break; 1818 #endif 1819 default: 1820 g_assert_not_reached(); 1821 } 1822 return ret; 1823 } 1824 1825 static void gen_conditional_jump_labels(DisasContext *s, target_long diff, 1826 TCGLabel *not_taken, TCGLabel *taken) 1827 { 1828 if (not_taken) { 1829 gen_set_label(not_taken); 1830 } 1831 gen_jmp_rel_csize(s, 0, 1); 1832 1833 gen_set_label(taken); 1834 gen_jmp_rel(s, s->dflag, diff, 0); 1835 } 1836 1837 static void gen_jcc(DisasContext *s, int b, int diff) 1838 { 1839 TCGLabel *l1 = gen_new_label(); 1840 1841 gen_jcc1(s, b, l1); 1842 gen_conditional_jump_labels(s, diff, NULL, l1); 1843 } 1844 1845 static void gen_cmovcc1(DisasContext *s, int b, TCGv dest, TCGv src) 1846 { 1847 CCPrepare cc = gen_prepare_cc(s, b, NULL); 1848 1849 if (!cc.use_reg2) { 1850 cc.reg2 = tcg_constant_tl(cc.imm); 1851 } 1852 1853 tcg_gen_movcond_tl(cc.cond, dest, cc.reg, cc.reg2, src, dest); 1854 } 1855 1856 static void gen_op_movl_seg_real(DisasContext *s, X86Seg seg_reg, TCGv seg) 1857 { 1858 TCGv selector = tcg_temp_new(); 1859 tcg_gen_ext16u_tl(selector, seg); 1860 tcg_gen_st32_tl(selector, tcg_env, 1861 offsetof(CPUX86State,segs[seg_reg].selector)); 1862 tcg_gen_shli_tl(cpu_seg_base[seg_reg], selector, 4); 1863 } 1864 1865 /* move SRC to seg_reg and compute if the CPU state may change. Never 1866 call this function with seg_reg == R_CS */ 1867 static void gen_movl_seg(DisasContext *s, X86Seg seg_reg, TCGv src) 1868 { 1869 if (PE(s) && !VM86(s)) { 1870 tcg_gen_trunc_tl_i32(s->tmp2_i32, src); 1871 gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32); 1872 /* abort translation because the addseg value may change or 1873 because ss32 may change. For R_SS, translation must always 1874 stop as a special handling must be done to disable hardware 1875 interrupts for the next instruction */ 1876 if (seg_reg == R_SS) { 1877 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 1878 } else if (CODE32(s) && seg_reg < R_FS) { 1879 s->base.is_jmp = DISAS_EOB_NEXT; 1880 } 1881 } else { 1882 gen_op_movl_seg_real(s, seg_reg, src); 1883 if (seg_reg == R_SS) { 1884 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ; 1885 } 1886 } 1887 } 1888 1889 static void gen_far_call(DisasContext *s) 1890 { 1891 TCGv_i32 new_cs = tcg_temp_new_i32(); 1892 tcg_gen_trunc_tl_i32(new_cs, s->T1); 1893 if (PE(s) && !VM86(s)) { 1894 gen_helper_lcall_protected(tcg_env, new_cs, s->T0, 1895 tcg_constant_i32(s->dflag - 1), 1896 eip_next_tl(s)); 1897 } else { 1898 TCGv_i32 new_eip = tcg_temp_new_i32(); 1899 tcg_gen_trunc_tl_i32(new_eip, s->T0); 1900 gen_helper_lcall_real(tcg_env, new_cs, new_eip, 1901 tcg_constant_i32(s->dflag - 1), 1902 eip_next_i32(s)); 1903 } 1904 s->base.is_jmp = DISAS_JUMP; 1905 } 1906 1907 static void gen_far_jmp(DisasContext *s) 1908 { 1909 if (PE(s) && !VM86(s)) { 1910 TCGv_i32 new_cs = tcg_temp_new_i32(); 1911 tcg_gen_trunc_tl_i32(new_cs, s->T1); 1912 gen_helper_ljmp_protected(tcg_env, new_cs, s->T0, 1913 eip_next_tl(s)); 1914 } else { 1915 gen_op_movl_seg_real(s, R_CS, s->T1); 1916 gen_op_jmp_v(s, s->T0); 1917 } 1918 s->base.is_jmp = DISAS_JUMP; 1919 } 1920 1921 static void gen_svm_check_intercept(DisasContext *s, uint32_t type) 1922 { 1923 /* no SVM activated; fast case */ 1924 if (likely(!GUEST(s))) { 1925 return; 1926 } 1927 gen_helper_svm_check_intercept(tcg_env, tcg_constant_i32(type)); 1928 } 1929 1930 static inline void gen_stack_update(DisasContext *s, int addend) 1931 { 1932 gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend); 1933 } 1934 1935 static void gen_lea_ss_ofs(DisasContext *s, TCGv dest, TCGv src, target_ulong offset) 1936 { 1937 if (offset) { 1938 tcg_gen_addi_tl(dest, src, offset); 1939 src = dest; 1940 } 1941 gen_lea_v_seg_dest(s, mo_stacksize(s), dest, src, R_SS, -1); 1942 } 1943 1944 /* Generate a push. It depends on ss32, addseg and dflag. */ 1945 static void gen_push_v(DisasContext *s, TCGv val) 1946 { 1947 MemOp d_ot = mo_pushpop(s, s->dflag); 1948 MemOp a_ot = mo_stacksize(s); 1949 int size = 1 << d_ot; 1950 TCGv new_esp = tcg_temp_new(); 1951 1952 tcg_gen_subi_tl(new_esp, cpu_regs[R_ESP], size); 1953 1954 /* Now reduce the value to the address size and apply SS base. */ 1955 gen_lea_ss_ofs(s, s->A0, new_esp, 0); 1956 gen_op_st_v(s, d_ot, val, s->A0); 1957 gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp); 1958 } 1959 1960 /* two step pop is necessary for precise exceptions */ 1961 static MemOp gen_pop_T0(DisasContext *s) 1962 { 1963 MemOp d_ot = mo_pushpop(s, s->dflag); 1964 1965 gen_lea_ss_ofs(s, s->T0, cpu_regs[R_ESP], 0); 1966 gen_op_ld_v(s, d_ot, s->T0, s->T0); 1967 1968 return d_ot; 1969 } 1970 1971 static inline void gen_pop_update(DisasContext *s, MemOp ot) 1972 { 1973 gen_stack_update(s, 1 << ot); 1974 } 1975 1976 static void gen_pusha(DisasContext *s) 1977 { 1978 MemOp d_ot = s->dflag; 1979 int size = 1 << d_ot; 1980 int i; 1981 1982 for (i = 0; i < 8; i++) { 1983 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], (i - 8) * size); 1984 gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0); 1985 } 1986 1987 gen_stack_update(s, -8 * size); 1988 } 1989 1990 static void gen_popa(DisasContext *s) 1991 { 1992 MemOp d_ot = s->dflag; 1993 int size = 1 << d_ot; 1994 int i; 1995 1996 for (i = 0; i < 8; i++) { 1997 /* ESP is not reloaded */ 1998 if (7 - i == R_ESP) { 1999 continue; 2000 } 2001 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], i * size); 2002 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2003 gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0); 2004 } 2005 2006 gen_stack_update(s, 8 * size); 2007 } 2008 2009 static void gen_enter(DisasContext *s, int esp_addend, int level) 2010 { 2011 MemOp d_ot = mo_pushpop(s, s->dflag); 2012 MemOp a_ot = mo_stacksize(s); 2013 int size = 1 << d_ot; 2014 2015 /* Push BP; compute FrameTemp into T1. */ 2016 tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size); 2017 gen_lea_ss_ofs(s, s->A0, s->T1, 0); 2018 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0); 2019 2020 level &= 31; 2021 if (level != 0) { 2022 int i; 2023 2024 /* Copy level-1 pointers from the previous frame. */ 2025 for (i = 1; i < level; ++i) { 2026 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], -size * i); 2027 gen_op_ld_v(s, d_ot, s->tmp0, s->A0); 2028 2029 gen_lea_ss_ofs(s, s->A0, s->T1, -size * i); 2030 gen_op_st_v(s, d_ot, s->tmp0, s->A0); 2031 } 2032 2033 /* Push the current FrameTemp as the last level. */ 2034 gen_lea_ss_ofs(s, s->A0, s->T1, -size * level); 2035 gen_op_st_v(s, d_ot, s->T1, s->A0); 2036 } 2037 2038 /* Copy the FrameTemp value to EBP. */ 2039 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T1); 2040 2041 /* Compute the final value of ESP. */ 2042 tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level); 2043 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2044 } 2045 2046 static void gen_leave(DisasContext *s) 2047 { 2048 MemOp d_ot = mo_pushpop(s, s->dflag); 2049 MemOp a_ot = mo_stacksize(s); 2050 2051 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], 0); 2052 gen_op_ld_v(s, d_ot, s->T0, s->A0); 2053 2054 tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot); 2055 2056 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0); 2057 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); 2058 } 2059 2060 /* Similarly, except that the assumption here is that we don't decode 2061 the instruction at all -- either a missing opcode, an unimplemented 2062 feature, or just a bogus instruction stream. */ 2063 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) 2064 { 2065 gen_illegal_opcode(s); 2066 2067 if (qemu_loglevel_mask(LOG_UNIMP)) { 2068 FILE *logfile = qemu_log_trylock(); 2069 if (logfile) { 2070 target_ulong pc = s->base.pc_next, end = s->pc; 2071 2072 fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc); 2073 for (; pc < end; ++pc) { 2074 fprintf(logfile, " %02x", translator_ldub(env, &s->base, pc)); 2075 } 2076 fprintf(logfile, "\n"); 2077 qemu_log_unlock(logfile); 2078 } 2079 } 2080 } 2081 2082 /* an interrupt is different from an exception because of the 2083 privilege checks */ 2084 static void gen_interrupt(DisasContext *s, uint8_t intno) 2085 { 2086 gen_update_cc_op(s); 2087 gen_update_eip_cur(s); 2088 gen_helper_raise_interrupt(tcg_env, tcg_constant_i32(intno), 2089 cur_insn_len_i32(s)); 2090 s->base.is_jmp = DISAS_NORETURN; 2091 } 2092 2093 static void gen_set_hflag(DisasContext *s, uint32_t mask) 2094 { 2095 if ((s->flags & mask) == 0) { 2096 TCGv_i32 t = tcg_temp_new_i32(); 2097 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2098 tcg_gen_ori_i32(t, t, mask); 2099 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2100 s->flags |= mask; 2101 } 2102 } 2103 2104 static void gen_reset_hflag(DisasContext *s, uint32_t mask) 2105 { 2106 if (s->flags & mask) { 2107 TCGv_i32 t = tcg_temp_new_i32(); 2108 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2109 tcg_gen_andi_i32(t, t, ~mask); 2110 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags)); 2111 s->flags &= ~mask; 2112 } 2113 } 2114 2115 static void gen_set_eflags(DisasContext *s, target_ulong mask) 2116 { 2117 TCGv t = tcg_temp_new(); 2118 2119 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2120 tcg_gen_ori_tl(t, t, mask); 2121 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2122 } 2123 2124 static void gen_reset_eflags(DisasContext *s, target_ulong mask) 2125 { 2126 TCGv t = tcg_temp_new(); 2127 2128 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2129 tcg_gen_andi_tl(t, t, ~mask); 2130 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags)); 2131 } 2132 2133 /* Clear BND registers during legacy branches. */ 2134 static void gen_bnd_jmp(DisasContext *s) 2135 { 2136 /* Clear the registers only if BND prefix is missing, MPX is enabled, 2137 and if the BNDREGs are known to be in use (non-zero) already. 2138 The helper itself will check BNDPRESERVE at runtime. */ 2139 if ((s->prefix & PREFIX_REPNZ) == 0 2140 && (s->flags & HF_MPX_EN_MASK) != 0 2141 && (s->flags & HF_MPX_IU_MASK) != 0) { 2142 gen_helper_bnd_jmp(tcg_env); 2143 } 2144 } 2145 2146 /* 2147 * Generate an end of block, including common tasks such as generating 2148 * single step traps, resetting the RF flag, and handling the interrupt 2149 * shadow. 2150 */ 2151 static void 2152 gen_eob(DisasContext *s, int mode) 2153 { 2154 bool inhibit_reset; 2155 2156 gen_update_cc_op(s); 2157 2158 /* If several instructions disable interrupts, only the first does it. */ 2159 inhibit_reset = false; 2160 if (s->flags & HF_INHIBIT_IRQ_MASK) { 2161 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); 2162 inhibit_reset = true; 2163 } else if (mode == DISAS_EOB_INHIBIT_IRQ) { 2164 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); 2165 } 2166 2167 if (s->base.tb->flags & HF_RF_MASK) { 2168 gen_reset_eflags(s, RF_MASK); 2169 } 2170 if (mode == DISAS_EOB_RECHECK_TF) { 2171 gen_helper_rechecking_single_step(tcg_env); 2172 tcg_gen_exit_tb(NULL, 0); 2173 } else if ((s->flags & HF_TF_MASK) && mode != DISAS_EOB_INHIBIT_IRQ) { 2174 gen_helper_single_step(tcg_env); 2175 } else if (mode == DISAS_JUMP && 2176 /* give irqs a chance to happen */ 2177 !inhibit_reset) { 2178 tcg_gen_lookup_and_goto_ptr(); 2179 } else { 2180 tcg_gen_exit_tb(NULL, 0); 2181 } 2182 2183 s->base.is_jmp = DISAS_NORETURN; 2184 } 2185 2186 /* Jump to eip+diff, truncating the result to OT. */ 2187 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num) 2188 { 2189 bool use_goto_tb = s->jmp_opt; 2190 target_ulong mask = -1; 2191 target_ulong new_pc = s->pc + diff; 2192 target_ulong new_eip = new_pc - s->cs_base; 2193 2194 assert(!s->cc_op_dirty); 2195 2196 /* In 64-bit mode, operand size is fixed at 64 bits. */ 2197 if (!CODE64(s)) { 2198 if (ot == MO_16) { 2199 mask = 0xffff; 2200 if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) { 2201 use_goto_tb = false; 2202 } 2203 } else { 2204 mask = 0xffffffff; 2205 } 2206 } 2207 new_eip &= mask; 2208 2209 if (tb_cflags(s->base.tb) & CF_PCREL) { 2210 tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save); 2211 /* 2212 * If we can prove the branch does not leave the page and we have 2213 * no extra masking to apply (data16 branch in code32, see above), 2214 * then we have also proven that the addition does not wrap. 2215 */ 2216 if (!use_goto_tb || !is_same_page(&s->base, new_pc)) { 2217 tcg_gen_andi_tl(cpu_eip, cpu_eip, mask); 2218 use_goto_tb = false; 2219 } 2220 } else if (!CODE64(s)) { 2221 new_pc = (uint32_t)(new_eip + s->cs_base); 2222 } 2223 2224 if (use_goto_tb && translator_use_goto_tb(&s->base, new_pc)) { 2225 /* jump to same page: we can use a direct jump */ 2226 tcg_gen_goto_tb(tb_num); 2227 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2228 tcg_gen_movi_tl(cpu_eip, new_eip); 2229 } 2230 tcg_gen_exit_tb(s->base.tb, tb_num); 2231 s->base.is_jmp = DISAS_NORETURN; 2232 } else { 2233 if (!(tb_cflags(s->base.tb) & CF_PCREL)) { 2234 tcg_gen_movi_tl(cpu_eip, new_eip); 2235 } 2236 if (s->jmp_opt) { 2237 gen_eob(s, DISAS_JUMP); /* jump to another page */ 2238 } else { 2239 gen_eob(s, DISAS_EOB_ONLY); /* exit to main loop */ 2240 } 2241 } 2242 } 2243 2244 /* Jump to eip+diff, truncating to the current code size. */ 2245 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num) 2246 { 2247 /* CODE64 ignores the OT argument, so we need not consider it. */ 2248 gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num); 2249 } 2250 2251 static inline void gen_ldq_env_A0(DisasContext *s, int offset) 2252 { 2253 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2254 tcg_gen_st_i64(s->tmp1_i64, tcg_env, offset); 2255 } 2256 2257 static inline void gen_stq_env_A0(DisasContext *s, int offset) 2258 { 2259 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, offset); 2260 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); 2261 } 2262 2263 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align) 2264 { 2265 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2266 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2267 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2268 int mem_index = s->mem_index; 2269 TCGv_i128 t = tcg_temp_new_i128(); 2270 2271 tcg_gen_qemu_ld_i128(t, s->A0, mem_index, mop); 2272 tcg_gen_st_i128(t, tcg_env, offset); 2273 } 2274 2275 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align) 2276 { 2277 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX 2278 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR); 2279 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0); 2280 int mem_index = s->mem_index; 2281 TCGv_i128 t = tcg_temp_new_i128(); 2282 2283 tcg_gen_ld_i128(t, tcg_env, offset); 2284 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop); 2285 } 2286 2287 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align) 2288 { 2289 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2290 int mem_index = s->mem_index; 2291 TCGv_i128 t0 = tcg_temp_new_i128(); 2292 TCGv_i128 t1 = tcg_temp_new_i128(); 2293 2294 tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2295 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2296 tcg_gen_qemu_ld_i128(t1, s->tmp0, mem_index, mop); 2297 2298 tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2299 tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2300 } 2301 2302 static void gen_sty_env_A0(DisasContext *s, int offset, bool align) 2303 { 2304 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; 2305 int mem_index = s->mem_index; 2306 TCGv_i128 t = tcg_temp_new_i128(); 2307 2308 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); 2309 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); 2310 tcg_gen_addi_tl(s->tmp0, s->A0, 16); 2311 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); 2312 tcg_gen_qemu_st_i128(t, s->tmp0, mem_index, mop); 2313 } 2314 2315 static void gen_cmpxchg8b(DisasContext *s, CPUX86State *env, int modrm) 2316 { 2317 TCGv_i64 cmp, val, old; 2318 TCGv Z; 2319 2320 gen_lea_modrm(env, s, modrm); 2321 2322 cmp = tcg_temp_new_i64(); 2323 val = tcg_temp_new_i64(); 2324 old = tcg_temp_new_i64(); 2325 2326 /* Construct the comparison values from the register pair. */ 2327 tcg_gen_concat_tl_i64(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]); 2328 tcg_gen_concat_tl_i64(val, cpu_regs[R_EBX], cpu_regs[R_ECX]); 2329 2330 /* Only require atomic with LOCK; non-parallel handled in generator. */ 2331 if (s->prefix & PREFIX_LOCK) { 2332 tcg_gen_atomic_cmpxchg_i64(old, s->A0, cmp, val, s->mem_index, MO_TEUQ); 2333 } else { 2334 tcg_gen_nonatomic_cmpxchg_i64(old, s->A0, cmp, val, 2335 s->mem_index, MO_TEUQ); 2336 } 2337 2338 /* Set tmp0 to match the required value of Z. */ 2339 tcg_gen_setcond_i64(TCG_COND_EQ, cmp, old, cmp); 2340 Z = tcg_temp_new(); 2341 tcg_gen_trunc_i64_tl(Z, cmp); 2342 2343 /* 2344 * Extract the result values for the register pair. 2345 * For 32-bit, we may do this unconditionally, because on success (Z=1), 2346 * the old value matches the previous value in EDX:EAX. For x86_64, 2347 * the store must be conditional, because we must leave the source 2348 * registers unchanged on success, and zero-extend the writeback 2349 * on failure (Z=0). 2350 */ 2351 if (TARGET_LONG_BITS == 32) { 2352 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], old); 2353 } else { 2354 TCGv zero = tcg_constant_tl(0); 2355 2356 tcg_gen_extr_i64_tl(s->T0, s->T1, old); 2357 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EAX], Z, zero, 2358 s->T0, cpu_regs[R_EAX]); 2359 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EDX], Z, zero, 2360 s->T1, cpu_regs[R_EDX]); 2361 } 2362 2363 /* Update Z. */ 2364 gen_compute_eflags(s); 2365 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, Z, ctz32(CC_Z), 1); 2366 } 2367 2368 #ifdef TARGET_X86_64 2369 static void gen_cmpxchg16b(DisasContext *s, CPUX86State *env, int modrm) 2370 { 2371 MemOp mop = MO_TE | MO_128 | MO_ALIGN; 2372 TCGv_i64 t0, t1; 2373 TCGv_i128 cmp, val; 2374 2375 gen_lea_modrm(env, s, modrm); 2376 2377 cmp = tcg_temp_new_i128(); 2378 val = tcg_temp_new_i128(); 2379 tcg_gen_concat_i64_i128(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]); 2380 tcg_gen_concat_i64_i128(val, cpu_regs[R_EBX], cpu_regs[R_ECX]); 2381 2382 /* Only require atomic with LOCK; non-parallel handled in generator. */ 2383 if (s->prefix & PREFIX_LOCK) { 2384 tcg_gen_atomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop); 2385 } else { 2386 tcg_gen_nonatomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop); 2387 } 2388 2389 tcg_gen_extr_i128_i64(s->T0, s->T1, val); 2390 2391 /* Determine success after the fact. */ 2392 t0 = tcg_temp_new_i64(); 2393 t1 = tcg_temp_new_i64(); 2394 tcg_gen_xor_i64(t0, s->T0, cpu_regs[R_EAX]); 2395 tcg_gen_xor_i64(t1, s->T1, cpu_regs[R_EDX]); 2396 tcg_gen_or_i64(t0, t0, t1); 2397 2398 /* Update Z. */ 2399 gen_compute_eflags(s); 2400 tcg_gen_setcondi_i64(TCG_COND_EQ, t0, t0, 0); 2401 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, t0, ctz32(CC_Z), 1); 2402 2403 /* 2404 * Extract the result values for the register pair. We may do this 2405 * unconditionally, because on success (Z=1), the old value matches 2406 * the previous value in RDX:RAX. 2407 */ 2408 tcg_gen_mov_i64(cpu_regs[R_EAX], s->T0); 2409 tcg_gen_mov_i64(cpu_regs[R_EDX], s->T1); 2410 } 2411 #endif 2412 2413 static bool disas_insn_x87(DisasContext *s, CPUState *cpu, int b) 2414 { 2415 CPUX86State *env = cpu_env(cpu); 2416 bool update_fip = true; 2417 int modrm, mod, rm, op; 2418 2419 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 2420 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 2421 /* XXX: what to do if illegal op ? */ 2422 gen_exception(s, EXCP07_PREX); 2423 return true; 2424 } 2425 modrm = x86_ldub_code(env, s); 2426 mod = (modrm >> 6) & 3; 2427 rm = modrm & 7; 2428 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 2429 if (mod != 3) { 2430 /* memory op */ 2431 AddressParts a = gen_lea_modrm_0(env, s, modrm, false); 2432 TCGv ea = gen_lea_modrm_1(s, a, false); 2433 TCGv last_addr = tcg_temp_new(); 2434 bool update_fdp = true; 2435 2436 tcg_gen_mov_tl(last_addr, ea); 2437 gen_lea_v_seg(s, ea, a.def_seg, s->override); 2438 2439 switch (op) { 2440 case 0x00 ... 0x07: /* fxxxs */ 2441 case 0x10 ... 0x17: /* fixxxl */ 2442 case 0x20 ... 0x27: /* fxxxl */ 2443 case 0x30 ... 0x37: /* fixxx */ 2444 { 2445 int op1; 2446 op1 = op & 7; 2447 2448 switch (op >> 4) { 2449 case 0: 2450 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2451 s->mem_index, MO_LEUL); 2452 gen_helper_flds_FT0(tcg_env, s->tmp2_i32); 2453 break; 2454 case 1: 2455 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2456 s->mem_index, MO_LEUL); 2457 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2458 break; 2459 case 2: 2460 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2461 s->mem_index, MO_LEUQ); 2462 gen_helper_fldl_FT0(tcg_env, s->tmp1_i64); 2463 break; 2464 case 3: 2465 default: 2466 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2467 s->mem_index, MO_LESW); 2468 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32); 2469 break; 2470 } 2471 2472 gen_helper_fp_arith_ST0_FT0(op1); 2473 if (op1 == 3) { 2474 /* fcomp needs pop */ 2475 gen_helper_fpop(tcg_env); 2476 } 2477 } 2478 break; 2479 case 0x08: /* flds */ 2480 case 0x0a: /* fsts */ 2481 case 0x0b: /* fstps */ 2482 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 2483 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 2484 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 2485 switch (op & 7) { 2486 case 0: 2487 switch (op >> 4) { 2488 case 0: 2489 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2490 s->mem_index, MO_LEUL); 2491 gen_helper_flds_ST0(tcg_env, s->tmp2_i32); 2492 break; 2493 case 1: 2494 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2495 s->mem_index, MO_LEUL); 2496 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2497 break; 2498 case 2: 2499 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2500 s->mem_index, MO_LEUQ); 2501 gen_helper_fldl_ST0(tcg_env, s->tmp1_i64); 2502 break; 2503 case 3: 2504 default: 2505 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2506 s->mem_index, MO_LESW); 2507 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32); 2508 break; 2509 } 2510 break; 2511 case 1: 2512 /* XXX: the corresponding CPUID bit must be tested ! */ 2513 switch (op >> 4) { 2514 case 1: 2515 gen_helper_fisttl_ST0(s->tmp2_i32, tcg_env); 2516 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2517 s->mem_index, MO_LEUL); 2518 break; 2519 case 2: 2520 gen_helper_fisttll_ST0(s->tmp1_i64, tcg_env); 2521 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2522 s->mem_index, MO_LEUQ); 2523 break; 2524 case 3: 2525 default: 2526 gen_helper_fistt_ST0(s->tmp2_i32, tcg_env); 2527 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2528 s->mem_index, MO_LEUW); 2529 break; 2530 } 2531 gen_helper_fpop(tcg_env); 2532 break; 2533 default: 2534 switch (op >> 4) { 2535 case 0: 2536 gen_helper_fsts_ST0(s->tmp2_i32, tcg_env); 2537 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2538 s->mem_index, MO_LEUL); 2539 break; 2540 case 1: 2541 gen_helper_fistl_ST0(s->tmp2_i32, tcg_env); 2542 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2543 s->mem_index, MO_LEUL); 2544 break; 2545 case 2: 2546 gen_helper_fstl_ST0(s->tmp1_i64, tcg_env); 2547 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2548 s->mem_index, MO_LEUQ); 2549 break; 2550 case 3: 2551 default: 2552 gen_helper_fist_ST0(s->tmp2_i32, tcg_env); 2553 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2554 s->mem_index, MO_LEUW); 2555 break; 2556 } 2557 if ((op & 7) == 3) { 2558 gen_helper_fpop(tcg_env); 2559 } 2560 break; 2561 } 2562 break; 2563 case 0x0c: /* fldenv mem */ 2564 gen_helper_fldenv(tcg_env, s->A0, 2565 tcg_constant_i32(s->dflag - 1)); 2566 update_fip = update_fdp = false; 2567 break; 2568 case 0x0d: /* fldcw mem */ 2569 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, 2570 s->mem_index, MO_LEUW); 2571 gen_helper_fldcw(tcg_env, s->tmp2_i32); 2572 update_fip = update_fdp = false; 2573 break; 2574 case 0x0e: /* fnstenv mem */ 2575 gen_helper_fstenv(tcg_env, s->A0, 2576 tcg_constant_i32(s->dflag - 1)); 2577 update_fip = update_fdp = false; 2578 break; 2579 case 0x0f: /* fnstcw mem */ 2580 gen_helper_fnstcw(s->tmp2_i32, tcg_env); 2581 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2582 s->mem_index, MO_LEUW); 2583 update_fip = update_fdp = false; 2584 break; 2585 case 0x1d: /* fldt mem */ 2586 gen_helper_fldt_ST0(tcg_env, s->A0); 2587 break; 2588 case 0x1f: /* fstpt mem */ 2589 gen_helper_fstt_ST0(tcg_env, s->A0); 2590 gen_helper_fpop(tcg_env); 2591 break; 2592 case 0x2c: /* frstor mem */ 2593 gen_helper_frstor(tcg_env, s->A0, 2594 tcg_constant_i32(s->dflag - 1)); 2595 update_fip = update_fdp = false; 2596 break; 2597 case 0x2e: /* fnsave mem */ 2598 gen_helper_fsave(tcg_env, s->A0, 2599 tcg_constant_i32(s->dflag - 1)); 2600 update_fip = update_fdp = false; 2601 break; 2602 case 0x2f: /* fnstsw mem */ 2603 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2604 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, 2605 s->mem_index, MO_LEUW); 2606 update_fip = update_fdp = false; 2607 break; 2608 case 0x3c: /* fbld */ 2609 gen_helper_fbld_ST0(tcg_env, s->A0); 2610 break; 2611 case 0x3e: /* fbstp */ 2612 gen_helper_fbst_ST0(tcg_env, s->A0); 2613 gen_helper_fpop(tcg_env); 2614 break; 2615 case 0x3d: /* fildll */ 2616 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, 2617 s->mem_index, MO_LEUQ); 2618 gen_helper_fildll_ST0(tcg_env, s->tmp1_i64); 2619 break; 2620 case 0x3f: /* fistpll */ 2621 gen_helper_fistll_ST0(s->tmp1_i64, tcg_env); 2622 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, 2623 s->mem_index, MO_LEUQ); 2624 gen_helper_fpop(tcg_env); 2625 break; 2626 default: 2627 return false; 2628 } 2629 2630 if (update_fdp) { 2631 int last_seg = s->override >= 0 ? s->override : a.def_seg; 2632 2633 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 2634 offsetof(CPUX86State, 2635 segs[last_seg].selector)); 2636 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 2637 offsetof(CPUX86State, fpds)); 2638 tcg_gen_st_tl(last_addr, tcg_env, 2639 offsetof(CPUX86State, fpdp)); 2640 } 2641 } else { 2642 /* register float ops */ 2643 int opreg = rm; 2644 2645 switch (op) { 2646 case 0x08: /* fld sti */ 2647 gen_helper_fpush(tcg_env); 2648 gen_helper_fmov_ST0_STN(tcg_env, 2649 tcg_constant_i32((opreg + 1) & 7)); 2650 break; 2651 case 0x09: /* fxchg sti */ 2652 case 0x29: /* fxchg4 sti, undocumented op */ 2653 case 0x39: /* fxchg7 sti, undocumented op */ 2654 gen_helper_fxchg_ST0_STN(tcg_env, tcg_constant_i32(opreg)); 2655 break; 2656 case 0x0a: /* grp d9/2 */ 2657 switch (rm) { 2658 case 0: /* fnop */ 2659 /* 2660 * check exceptions (FreeBSD FPU probe) 2661 * needs to be treated as I/O because of ferr_irq 2662 */ 2663 translator_io_start(&s->base); 2664 gen_helper_fwait(tcg_env); 2665 update_fip = false; 2666 break; 2667 default: 2668 return false; 2669 } 2670 break; 2671 case 0x0c: /* grp d9/4 */ 2672 switch (rm) { 2673 case 0: /* fchs */ 2674 gen_helper_fchs_ST0(tcg_env); 2675 break; 2676 case 1: /* fabs */ 2677 gen_helper_fabs_ST0(tcg_env); 2678 break; 2679 case 4: /* ftst */ 2680 gen_helper_fldz_FT0(tcg_env); 2681 gen_helper_fcom_ST0_FT0(tcg_env); 2682 break; 2683 case 5: /* fxam */ 2684 gen_helper_fxam_ST0(tcg_env); 2685 break; 2686 default: 2687 return false; 2688 } 2689 break; 2690 case 0x0d: /* grp d9/5 */ 2691 { 2692 switch (rm) { 2693 case 0: 2694 gen_helper_fpush(tcg_env); 2695 gen_helper_fld1_ST0(tcg_env); 2696 break; 2697 case 1: 2698 gen_helper_fpush(tcg_env); 2699 gen_helper_fldl2t_ST0(tcg_env); 2700 break; 2701 case 2: 2702 gen_helper_fpush(tcg_env); 2703 gen_helper_fldl2e_ST0(tcg_env); 2704 break; 2705 case 3: 2706 gen_helper_fpush(tcg_env); 2707 gen_helper_fldpi_ST0(tcg_env); 2708 break; 2709 case 4: 2710 gen_helper_fpush(tcg_env); 2711 gen_helper_fldlg2_ST0(tcg_env); 2712 break; 2713 case 5: 2714 gen_helper_fpush(tcg_env); 2715 gen_helper_fldln2_ST0(tcg_env); 2716 break; 2717 case 6: 2718 gen_helper_fpush(tcg_env); 2719 gen_helper_fldz_ST0(tcg_env); 2720 break; 2721 default: 2722 return false; 2723 } 2724 } 2725 break; 2726 case 0x0e: /* grp d9/6 */ 2727 switch (rm) { 2728 case 0: /* f2xm1 */ 2729 gen_helper_f2xm1(tcg_env); 2730 break; 2731 case 1: /* fyl2x */ 2732 gen_helper_fyl2x(tcg_env); 2733 break; 2734 case 2: /* fptan */ 2735 gen_helper_fptan(tcg_env); 2736 break; 2737 case 3: /* fpatan */ 2738 gen_helper_fpatan(tcg_env); 2739 break; 2740 case 4: /* fxtract */ 2741 gen_helper_fxtract(tcg_env); 2742 break; 2743 case 5: /* fprem1 */ 2744 gen_helper_fprem1(tcg_env); 2745 break; 2746 case 6: /* fdecstp */ 2747 gen_helper_fdecstp(tcg_env); 2748 break; 2749 default: 2750 case 7: /* fincstp */ 2751 gen_helper_fincstp(tcg_env); 2752 break; 2753 } 2754 break; 2755 case 0x0f: /* grp d9/7 */ 2756 switch (rm) { 2757 case 0: /* fprem */ 2758 gen_helper_fprem(tcg_env); 2759 break; 2760 case 1: /* fyl2xp1 */ 2761 gen_helper_fyl2xp1(tcg_env); 2762 break; 2763 case 2: /* fsqrt */ 2764 gen_helper_fsqrt(tcg_env); 2765 break; 2766 case 3: /* fsincos */ 2767 gen_helper_fsincos(tcg_env); 2768 break; 2769 case 5: /* fscale */ 2770 gen_helper_fscale(tcg_env); 2771 break; 2772 case 4: /* frndint */ 2773 gen_helper_frndint(tcg_env); 2774 break; 2775 case 6: /* fsin */ 2776 gen_helper_fsin(tcg_env); 2777 break; 2778 default: 2779 case 7: /* fcos */ 2780 gen_helper_fcos(tcg_env); 2781 break; 2782 } 2783 break; 2784 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 2785 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 2786 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 2787 { 2788 int op1; 2789 2790 op1 = op & 7; 2791 if (op >= 0x20) { 2792 gen_helper_fp_arith_STN_ST0(op1, opreg); 2793 if (op >= 0x30) { 2794 gen_helper_fpop(tcg_env); 2795 } 2796 } else { 2797 gen_helper_fmov_FT0_STN(tcg_env, 2798 tcg_constant_i32(opreg)); 2799 gen_helper_fp_arith_ST0_FT0(op1); 2800 } 2801 } 2802 break; 2803 case 0x02: /* fcom */ 2804 case 0x22: /* fcom2, undocumented op */ 2805 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2806 gen_helper_fcom_ST0_FT0(tcg_env); 2807 break; 2808 case 0x03: /* fcomp */ 2809 case 0x23: /* fcomp3, undocumented op */ 2810 case 0x32: /* fcomp5, undocumented op */ 2811 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2812 gen_helper_fcom_ST0_FT0(tcg_env); 2813 gen_helper_fpop(tcg_env); 2814 break; 2815 case 0x15: /* da/5 */ 2816 switch (rm) { 2817 case 1: /* fucompp */ 2818 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2819 gen_helper_fucom_ST0_FT0(tcg_env); 2820 gen_helper_fpop(tcg_env); 2821 gen_helper_fpop(tcg_env); 2822 break; 2823 default: 2824 return false; 2825 } 2826 break; 2827 case 0x1c: 2828 switch (rm) { 2829 case 0: /* feni (287 only, just do nop here) */ 2830 break; 2831 case 1: /* fdisi (287 only, just do nop here) */ 2832 break; 2833 case 2: /* fclex */ 2834 gen_helper_fclex(tcg_env); 2835 update_fip = false; 2836 break; 2837 case 3: /* fninit */ 2838 gen_helper_fninit(tcg_env); 2839 update_fip = false; 2840 break; 2841 case 4: /* fsetpm (287 only, just do nop here) */ 2842 break; 2843 default: 2844 return false; 2845 } 2846 break; 2847 case 0x1d: /* fucomi */ 2848 if (!(s->cpuid_features & CPUID_CMOV)) { 2849 goto illegal_op; 2850 } 2851 gen_update_cc_op(s); 2852 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2853 gen_helper_fucomi_ST0_FT0(tcg_env); 2854 assume_cc_op(s, CC_OP_EFLAGS); 2855 break; 2856 case 0x1e: /* fcomi */ 2857 if (!(s->cpuid_features & CPUID_CMOV)) { 2858 goto illegal_op; 2859 } 2860 gen_update_cc_op(s); 2861 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2862 gen_helper_fcomi_ST0_FT0(tcg_env); 2863 assume_cc_op(s, CC_OP_EFLAGS); 2864 break; 2865 case 0x28: /* ffree sti */ 2866 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2867 break; 2868 case 0x2a: /* fst sti */ 2869 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2870 break; 2871 case 0x2b: /* fstp sti */ 2872 case 0x0b: /* fstp1 sti, undocumented op */ 2873 case 0x3a: /* fstp8 sti, undocumented op */ 2874 case 0x3b: /* fstp9 sti, undocumented op */ 2875 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg)); 2876 gen_helper_fpop(tcg_env); 2877 break; 2878 case 0x2c: /* fucom st(i) */ 2879 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2880 gen_helper_fucom_ST0_FT0(tcg_env); 2881 break; 2882 case 0x2d: /* fucomp st(i) */ 2883 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2884 gen_helper_fucom_ST0_FT0(tcg_env); 2885 gen_helper_fpop(tcg_env); 2886 break; 2887 case 0x33: /* de/3 */ 2888 switch (rm) { 2889 case 1: /* fcompp */ 2890 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1)); 2891 gen_helper_fcom_ST0_FT0(tcg_env); 2892 gen_helper_fpop(tcg_env); 2893 gen_helper_fpop(tcg_env); 2894 break; 2895 default: 2896 return false; 2897 } 2898 break; 2899 case 0x38: /* ffreep sti, undocumented op */ 2900 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg)); 2901 gen_helper_fpop(tcg_env); 2902 break; 2903 case 0x3c: /* df/4 */ 2904 switch (rm) { 2905 case 0: 2906 gen_helper_fnstsw(s->tmp2_i32, tcg_env); 2907 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); 2908 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); 2909 break; 2910 default: 2911 return false; 2912 } 2913 break; 2914 case 0x3d: /* fucomip */ 2915 if (!(s->cpuid_features & CPUID_CMOV)) { 2916 goto illegal_op; 2917 } 2918 gen_update_cc_op(s); 2919 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2920 gen_helper_fucomi_ST0_FT0(tcg_env); 2921 gen_helper_fpop(tcg_env); 2922 assume_cc_op(s, CC_OP_EFLAGS); 2923 break; 2924 case 0x3e: /* fcomip */ 2925 if (!(s->cpuid_features & CPUID_CMOV)) { 2926 goto illegal_op; 2927 } 2928 gen_update_cc_op(s); 2929 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg)); 2930 gen_helper_fcomi_ST0_FT0(tcg_env); 2931 gen_helper_fpop(tcg_env); 2932 assume_cc_op(s, CC_OP_EFLAGS); 2933 break; 2934 case 0x10 ... 0x13: /* fcmovxx */ 2935 case 0x18 ... 0x1b: 2936 { 2937 int op1; 2938 TCGLabel *l1; 2939 static const uint8_t fcmov_cc[8] = { 2940 (JCC_B << 1), 2941 (JCC_Z << 1), 2942 (JCC_BE << 1), 2943 (JCC_P << 1), 2944 }; 2945 2946 if (!(s->cpuid_features & CPUID_CMOV)) { 2947 goto illegal_op; 2948 } 2949 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 2950 l1 = gen_new_label(); 2951 gen_jcc1_noeob(s, op1, l1); 2952 gen_helper_fmov_ST0_STN(tcg_env, 2953 tcg_constant_i32(opreg)); 2954 gen_set_label(l1); 2955 } 2956 break; 2957 default: 2958 return false; 2959 } 2960 } 2961 2962 if (update_fip) { 2963 tcg_gen_ld_i32(s->tmp2_i32, tcg_env, 2964 offsetof(CPUX86State, segs[R_CS].selector)); 2965 tcg_gen_st16_i32(s->tmp2_i32, tcg_env, 2966 offsetof(CPUX86State, fpcs)); 2967 tcg_gen_st_tl(eip_cur_tl(s), 2968 tcg_env, offsetof(CPUX86State, fpip)); 2969 } 2970 return true; 2971 2972 illegal_op: 2973 gen_illegal_opcode(s); 2974 return true; 2975 } 2976 2977 static void disas_insn_old(DisasContext *s, CPUState *cpu, int b) 2978 { 2979 CPUX86State *env = cpu_env(cpu); 2980 int prefixes = s->prefix; 2981 MemOp dflag = s->dflag; 2982 MemOp ot; 2983 int modrm, reg, rm, mod, op, val; 2984 2985 /* now check op code */ 2986 switch (b) { 2987 case 0x1c7: /* cmpxchg8b */ 2988 modrm = x86_ldub_code(env, s); 2989 mod = (modrm >> 6) & 3; 2990 switch ((modrm >> 3) & 7) { 2991 case 1: /* CMPXCHG8, CMPXCHG16 */ 2992 if (mod == 3) { 2993 goto illegal_op; 2994 } 2995 #ifdef TARGET_X86_64 2996 if (dflag == MO_64) { 2997 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) { 2998 goto illegal_op; 2999 } 3000 gen_cmpxchg16b(s, env, modrm); 3001 break; 3002 } 3003 #endif 3004 if (!(s->cpuid_features & CPUID_CX8)) { 3005 goto illegal_op; 3006 } 3007 gen_cmpxchg8b(s, env, modrm); 3008 break; 3009 3010 case 7: /* RDSEED, RDPID with f3 prefix */ 3011 if (mod != 3 || 3012 (s->prefix & (PREFIX_LOCK | PREFIX_REPNZ))) { 3013 goto illegal_op; 3014 } 3015 if (s->prefix & PREFIX_REPZ) { 3016 if (!(s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_RDPID)) { 3017 goto illegal_op; 3018 } 3019 gen_helper_rdpid(s->T0, tcg_env); 3020 rm = (modrm & 7) | REX_B(s); 3021 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3022 break; 3023 } else { 3024 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) { 3025 goto illegal_op; 3026 } 3027 goto do_rdrand; 3028 } 3029 3030 case 6: /* RDRAND */ 3031 if (mod != 3 || 3032 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) || 3033 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { 3034 goto illegal_op; 3035 } 3036 do_rdrand: 3037 translator_io_start(&s->base); 3038 gen_helper_rdrand(s->T0, tcg_env); 3039 rm = (modrm & 7) | REX_B(s); 3040 gen_op_mov_reg_v(s, dflag, rm, s->T0); 3041 assume_cc_op(s, CC_OP_EFLAGS); 3042 break; 3043 3044 default: 3045 goto illegal_op; 3046 } 3047 break; 3048 3049 /************************/ 3050 /* bit operations */ 3051 case 0x1ba: /* bt/bts/btr/btc Gv, im */ 3052 ot = dflag; 3053 modrm = x86_ldub_code(env, s); 3054 op = (modrm >> 3) & 7; 3055 mod = (modrm >> 6) & 3; 3056 rm = (modrm & 7) | REX_B(s); 3057 if (mod != 3) { 3058 s->rip_offset = 1; 3059 gen_lea_modrm(env, s, modrm); 3060 if (!(s->prefix & PREFIX_LOCK)) { 3061 gen_op_ld_v(s, ot, s->T0, s->A0); 3062 } 3063 } else { 3064 gen_op_mov_v_reg(s, ot, s->T0, rm); 3065 } 3066 /* load shift */ 3067 val = x86_ldub_code(env, s); 3068 tcg_gen_movi_tl(s->T1, val); 3069 if (op < 4) 3070 goto unknown_op; 3071 op -= 4; 3072 goto bt_op; 3073 case 0x1a3: /* bt Gv, Ev */ 3074 op = 0; 3075 goto do_btx; 3076 case 0x1ab: /* bts */ 3077 op = 1; 3078 goto do_btx; 3079 case 0x1b3: /* btr */ 3080 op = 2; 3081 goto do_btx; 3082 case 0x1bb: /* btc */ 3083 op = 3; 3084 do_btx: 3085 ot = dflag; 3086 modrm = x86_ldub_code(env, s); 3087 reg = ((modrm >> 3) & 7) | REX_R(s); 3088 mod = (modrm >> 6) & 3; 3089 rm = (modrm & 7) | REX_B(s); 3090 gen_op_mov_v_reg(s, MO_32, s->T1, reg); 3091 if (mod != 3) { 3092 AddressParts a = gen_lea_modrm_0(env, s, modrm, false); 3093 /* specific case: we need to add a displacement */ 3094 gen_exts(ot, s->T1); 3095 tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot); 3096 tcg_gen_shli_tl(s->tmp0, s->tmp0, ot); 3097 tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0); 3098 gen_lea_v_seg(s, s->A0, a.def_seg, s->override); 3099 if (!(s->prefix & PREFIX_LOCK)) { 3100 gen_op_ld_v(s, ot, s->T0, s->A0); 3101 } 3102 } else { 3103 gen_op_mov_v_reg(s, ot, s->T0, rm); 3104 } 3105 bt_op: 3106 tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1); 3107 tcg_gen_movi_tl(s->tmp0, 1); 3108 tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1); 3109 if (s->prefix & PREFIX_LOCK) { 3110 switch (op) { 3111 case 0: /* bt */ 3112 /* Needs no atomic ops; we suppressed the normal 3113 memory load for LOCK above so do it now. */ 3114 gen_op_ld_v(s, ot, s->T0, s->A0); 3115 break; 3116 case 1: /* bts */ 3117 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0, 3118 s->mem_index, ot | MO_LE); 3119 break; 3120 case 2: /* btr */ 3121 tcg_gen_not_tl(s->tmp0, s->tmp0); 3122 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0, 3123 s->mem_index, ot | MO_LE); 3124 break; 3125 default: 3126 case 3: /* btc */ 3127 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0, 3128 s->mem_index, ot | MO_LE); 3129 break; 3130 } 3131 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 3132 } else { 3133 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1); 3134 switch (op) { 3135 case 0: /* bt */ 3136 /* Data already loaded; nothing to do. */ 3137 break; 3138 case 1: /* bts */ 3139 tcg_gen_or_tl(s->T0, s->T0, s->tmp0); 3140 break; 3141 case 2: /* btr */ 3142 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0); 3143 break; 3144 default: 3145 case 3: /* btc */ 3146 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0); 3147 break; 3148 } 3149 if (op != 0) { 3150 if (mod != 3) { 3151 gen_op_st_v(s, ot, s->T0, s->A0); 3152 } else { 3153 gen_op_mov_reg_v(s, ot, rm, s->T0); 3154 } 3155 } 3156 } 3157 3158 /* Delay all CC updates until after the store above. Note that 3159 C is the result of the test, Z is unchanged, and the others 3160 are all undefined. */ 3161 switch (s->cc_op) { 3162 case CC_OP_MULB ... CC_OP_MULQ: 3163 case CC_OP_ADDB ... CC_OP_ADDQ: 3164 case CC_OP_ADCB ... CC_OP_ADCQ: 3165 case CC_OP_SUBB ... CC_OP_SUBQ: 3166 case CC_OP_SBBB ... CC_OP_SBBQ: 3167 case CC_OP_LOGICB ... CC_OP_LOGICQ: 3168 case CC_OP_INCB ... CC_OP_INCQ: 3169 case CC_OP_DECB ... CC_OP_DECQ: 3170 case CC_OP_SHLB ... CC_OP_SHLQ: 3171 case CC_OP_SARB ... CC_OP_SARQ: 3172 case CC_OP_BMILGB ... CC_OP_BMILGQ: 3173 case CC_OP_POPCNT: 3174 /* Z was going to be computed from the non-zero status of CC_DST. 3175 We can get that same Z value (and the new C value) by leaving 3176 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the 3177 same width. */ 3178 tcg_gen_mov_tl(cpu_cc_src, s->tmp4); 3179 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB); 3180 break; 3181 default: 3182 /* Otherwise, generate EFLAGS and replace the C bit. */ 3183 gen_compute_eflags(s); 3184 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4, 3185 ctz32(CC_C), 1); 3186 break; 3187 } 3188 break; 3189 case 0x100: 3190 modrm = x86_ldub_code(env, s); 3191 mod = (modrm >> 6) & 3; 3192 op = (modrm >> 3) & 7; 3193 switch(op) { 3194 case 0: /* sldt */ 3195 if (!PE(s) || VM86(s)) 3196 goto illegal_op; 3197 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3198 break; 3199 } 3200 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ); 3201 tcg_gen_ld32u_tl(s->T0, tcg_env, 3202 offsetof(CPUX86State, ldt.selector)); 3203 ot = mod == 3 ? dflag : MO_16; 3204 gen_st_modrm(env, s, modrm, ot); 3205 break; 3206 case 2: /* lldt */ 3207 if (!PE(s) || VM86(s)) 3208 goto illegal_op; 3209 if (check_cpl0(s)) { 3210 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE); 3211 gen_ld_modrm(env, s, modrm, MO_16); 3212 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3213 gen_helper_lldt(tcg_env, s->tmp2_i32); 3214 } 3215 break; 3216 case 1: /* str */ 3217 if (!PE(s) || VM86(s)) 3218 goto illegal_op; 3219 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3220 break; 3221 } 3222 gen_svm_check_intercept(s, SVM_EXIT_TR_READ); 3223 tcg_gen_ld32u_tl(s->T0, tcg_env, 3224 offsetof(CPUX86State, tr.selector)); 3225 ot = mod == 3 ? dflag : MO_16; 3226 gen_st_modrm(env, s, modrm, ot); 3227 break; 3228 case 3: /* ltr */ 3229 if (!PE(s) || VM86(s)) 3230 goto illegal_op; 3231 if (check_cpl0(s)) { 3232 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE); 3233 gen_ld_modrm(env, s, modrm, MO_16); 3234 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); 3235 gen_helper_ltr(tcg_env, s->tmp2_i32); 3236 } 3237 break; 3238 case 4: /* verr */ 3239 case 5: /* verw */ 3240 if (!PE(s) || VM86(s)) 3241 goto illegal_op; 3242 gen_ld_modrm(env, s, modrm, MO_16); 3243 gen_update_cc_op(s); 3244 if (op == 4) { 3245 gen_helper_verr(tcg_env, s->T0); 3246 } else { 3247 gen_helper_verw(tcg_env, s->T0); 3248 } 3249 assume_cc_op(s, CC_OP_EFLAGS); 3250 break; 3251 default: 3252 goto unknown_op; 3253 } 3254 break; 3255 3256 case 0x101: 3257 modrm = x86_ldub_code(env, s); 3258 switch (modrm) { 3259 CASE_MODRM_MEM_OP(0): /* sgdt */ 3260 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3261 break; 3262 } 3263 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ); 3264 gen_lea_modrm(env, s, modrm); 3265 tcg_gen_ld32u_tl(s->T0, 3266 tcg_env, offsetof(CPUX86State, gdt.limit)); 3267 gen_op_st_v(s, MO_16, s->T0, s->A0); 3268 gen_add_A0_im(s, 2); 3269 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3270 /* 3271 * NB: Despite a confusing description in Intel CPU documentation, 3272 * all 32-bits are written regardless of operand size. 3273 */ 3274 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3275 break; 3276 3277 case 0xc8: /* monitor */ 3278 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3279 goto illegal_op; 3280 } 3281 gen_update_cc_op(s); 3282 gen_update_eip_cur(s); 3283 gen_lea_v_seg(s, cpu_regs[R_EAX], R_DS, s->override); 3284 gen_helper_monitor(tcg_env, s->A0); 3285 break; 3286 3287 case 0xc9: /* mwait */ 3288 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) { 3289 goto illegal_op; 3290 } 3291 gen_update_cc_op(s); 3292 gen_update_eip_cur(s); 3293 gen_helper_mwait(tcg_env, cur_insn_len_i32(s)); 3294 s->base.is_jmp = DISAS_NORETURN; 3295 break; 3296 3297 case 0xca: /* clac */ 3298 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3299 || CPL(s) != 0) { 3300 goto illegal_op; 3301 } 3302 gen_reset_eflags(s, AC_MASK); 3303 s->base.is_jmp = DISAS_EOB_NEXT; 3304 break; 3305 3306 case 0xcb: /* stac */ 3307 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) 3308 || CPL(s) != 0) { 3309 goto illegal_op; 3310 } 3311 gen_set_eflags(s, AC_MASK); 3312 s->base.is_jmp = DISAS_EOB_NEXT; 3313 break; 3314 3315 CASE_MODRM_MEM_OP(1): /* sidt */ 3316 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3317 break; 3318 } 3319 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ); 3320 gen_lea_modrm(env, s, modrm); 3321 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.limit)); 3322 gen_op_st_v(s, MO_16, s->T0, s->A0); 3323 gen_add_A0_im(s, 2); 3324 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3325 /* 3326 * NB: Despite a confusing description in Intel CPU documentation, 3327 * all 32-bits are written regardless of operand size. 3328 */ 3329 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3330 break; 3331 3332 case 0xd0: /* xgetbv */ 3333 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3334 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3335 | PREFIX_REPZ | PREFIX_REPNZ))) { 3336 goto illegal_op; 3337 } 3338 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3339 gen_helper_xgetbv(s->tmp1_i64, tcg_env, s->tmp2_i32); 3340 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3341 break; 3342 3343 case 0xd1: /* xsetbv */ 3344 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 3345 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3346 | PREFIX_REPZ | PREFIX_REPNZ))) { 3347 goto illegal_op; 3348 } 3349 gen_svm_check_intercept(s, SVM_EXIT_XSETBV); 3350 if (!check_cpl0(s)) { 3351 break; 3352 } 3353 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3354 cpu_regs[R_EDX]); 3355 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3356 gen_helper_xsetbv(tcg_env, s->tmp2_i32, s->tmp1_i64); 3357 /* End TB because translation flags may change. */ 3358 s->base.is_jmp = DISAS_EOB_NEXT; 3359 break; 3360 3361 case 0xd8: /* VMRUN */ 3362 if (!SVME(s) || !PE(s)) { 3363 goto illegal_op; 3364 } 3365 if (!check_cpl0(s)) { 3366 break; 3367 } 3368 gen_update_cc_op(s); 3369 gen_update_eip_cur(s); 3370 /* 3371 * Reloads INHIBIT_IRQ mask as well as TF and RF with guest state. 3372 * The usual gen_eob() handling is performed on vmexit after 3373 * host state is reloaded. 3374 */ 3375 gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1), 3376 cur_insn_len_i32(s)); 3377 tcg_gen_exit_tb(NULL, 0); 3378 s->base.is_jmp = DISAS_NORETURN; 3379 break; 3380 3381 case 0xd9: /* VMMCALL */ 3382 if (!SVME(s)) { 3383 goto illegal_op; 3384 } 3385 gen_update_cc_op(s); 3386 gen_update_eip_cur(s); 3387 gen_helper_vmmcall(tcg_env); 3388 break; 3389 3390 case 0xda: /* VMLOAD */ 3391 if (!SVME(s) || !PE(s)) { 3392 goto illegal_op; 3393 } 3394 if (!check_cpl0(s)) { 3395 break; 3396 } 3397 gen_update_cc_op(s); 3398 gen_update_eip_cur(s); 3399 gen_helper_vmload(tcg_env, tcg_constant_i32(s->aflag - 1)); 3400 break; 3401 3402 case 0xdb: /* VMSAVE */ 3403 if (!SVME(s) || !PE(s)) { 3404 goto illegal_op; 3405 } 3406 if (!check_cpl0(s)) { 3407 break; 3408 } 3409 gen_update_cc_op(s); 3410 gen_update_eip_cur(s); 3411 gen_helper_vmsave(tcg_env, tcg_constant_i32(s->aflag - 1)); 3412 break; 3413 3414 case 0xdc: /* STGI */ 3415 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3416 || !PE(s)) { 3417 goto illegal_op; 3418 } 3419 if (!check_cpl0(s)) { 3420 break; 3421 } 3422 gen_update_cc_op(s); 3423 gen_helper_stgi(tcg_env); 3424 s->base.is_jmp = DISAS_EOB_NEXT; 3425 break; 3426 3427 case 0xdd: /* CLGI */ 3428 if (!SVME(s) || !PE(s)) { 3429 goto illegal_op; 3430 } 3431 if (!check_cpl0(s)) { 3432 break; 3433 } 3434 gen_update_cc_op(s); 3435 gen_update_eip_cur(s); 3436 gen_helper_clgi(tcg_env); 3437 break; 3438 3439 case 0xde: /* SKINIT */ 3440 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) 3441 || !PE(s)) { 3442 goto illegal_op; 3443 } 3444 gen_svm_check_intercept(s, SVM_EXIT_SKINIT); 3445 /* If not intercepted, not implemented -- raise #UD. */ 3446 goto illegal_op; 3447 3448 case 0xdf: /* INVLPGA */ 3449 if (!SVME(s) || !PE(s)) { 3450 goto illegal_op; 3451 } 3452 if (!check_cpl0(s)) { 3453 break; 3454 } 3455 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA); 3456 if (s->aflag == MO_64) { 3457 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]); 3458 } else { 3459 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]); 3460 } 3461 gen_helper_flush_page(tcg_env, s->A0); 3462 s->base.is_jmp = DISAS_EOB_NEXT; 3463 break; 3464 3465 CASE_MODRM_MEM_OP(2): /* lgdt */ 3466 if (!check_cpl0(s)) { 3467 break; 3468 } 3469 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE); 3470 gen_lea_modrm(env, s, modrm); 3471 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3472 gen_add_A0_im(s, 2); 3473 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3474 if (dflag == MO_16) { 3475 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3476 } 3477 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base)); 3478 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, gdt.limit)); 3479 break; 3480 3481 CASE_MODRM_MEM_OP(3): /* lidt */ 3482 if (!check_cpl0(s)) { 3483 break; 3484 } 3485 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE); 3486 gen_lea_modrm(env, s, modrm); 3487 gen_op_ld_v(s, MO_16, s->T1, s->A0); 3488 gen_add_A0_im(s, 2); 3489 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0); 3490 if (dflag == MO_16) { 3491 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff); 3492 } 3493 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base)); 3494 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, idt.limit)); 3495 break; 3496 3497 CASE_MODRM_OP(4): /* smsw */ 3498 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) { 3499 break; 3500 } 3501 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0); 3502 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, cr[0])); 3503 /* 3504 * In 32-bit mode, the higher 16 bits of the destination 3505 * register are undefined. In practice CR0[31:0] is stored 3506 * just like in 64-bit mode. 3507 */ 3508 mod = (modrm >> 6) & 3; 3509 ot = (mod != 3 ? MO_16 : s->dflag); 3510 gen_st_modrm(env, s, modrm, ot); 3511 break; 3512 case 0xee: /* rdpkru */ 3513 if (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3514 | PREFIX_REPZ | PREFIX_REPNZ)) { 3515 goto illegal_op; 3516 } 3517 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3518 gen_helper_rdpkru(s->tmp1_i64, tcg_env, s->tmp2_i32); 3519 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); 3520 break; 3521 case 0xef: /* wrpkru */ 3522 if (s->prefix & (PREFIX_LOCK | PREFIX_DATA 3523 | PREFIX_REPZ | PREFIX_REPNZ)) { 3524 goto illegal_op; 3525 } 3526 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], 3527 cpu_regs[R_EDX]); 3528 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); 3529 gen_helper_wrpkru(tcg_env, s->tmp2_i32, s->tmp1_i64); 3530 break; 3531 3532 CASE_MODRM_OP(6): /* lmsw */ 3533 if (!check_cpl0(s)) { 3534 break; 3535 } 3536 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); 3537 gen_ld_modrm(env, s, modrm, MO_16); 3538 /* 3539 * Only the 4 lower bits of CR0 are modified. 3540 * PE cannot be set to zero if already set to one. 3541 */ 3542 tcg_gen_ld_tl(s->T1, tcg_env, offsetof(CPUX86State, cr[0])); 3543 tcg_gen_andi_tl(s->T0, s->T0, 0xf); 3544 tcg_gen_andi_tl(s->T1, s->T1, ~0xe); 3545 tcg_gen_or_tl(s->T0, s->T0, s->T1); 3546 gen_helper_write_crN(tcg_env, tcg_constant_i32(0), s->T0); 3547 s->base.is_jmp = DISAS_EOB_NEXT; 3548 break; 3549 3550 CASE_MODRM_MEM_OP(7): /* invlpg */ 3551 if (!check_cpl0(s)) { 3552 break; 3553 } 3554 gen_svm_check_intercept(s, SVM_EXIT_INVLPG); 3555 gen_lea_modrm(env, s, modrm); 3556 gen_helper_flush_page(tcg_env, s->A0); 3557 s->base.is_jmp = DISAS_EOB_NEXT; 3558 break; 3559 3560 case 0xf8: /* swapgs */ 3561 #ifdef TARGET_X86_64 3562 if (CODE64(s)) { 3563 if (check_cpl0(s)) { 3564 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]); 3565 tcg_gen_ld_tl(cpu_seg_base[R_GS], tcg_env, 3566 offsetof(CPUX86State, kernelgsbase)); 3567 tcg_gen_st_tl(s->T0, tcg_env, 3568 offsetof(CPUX86State, kernelgsbase)); 3569 } 3570 break; 3571 } 3572 #endif 3573 goto illegal_op; 3574 3575 case 0xf9: /* rdtscp */ 3576 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) { 3577 goto illegal_op; 3578 } 3579 gen_update_cc_op(s); 3580 gen_update_eip_cur(s); 3581 translator_io_start(&s->base); 3582 gen_helper_rdtsc(tcg_env); 3583 gen_helper_rdpid(s->T0, tcg_env); 3584 gen_op_mov_reg_v(s, dflag, R_ECX, s->T0); 3585 break; 3586 3587 default: 3588 goto unknown_op; 3589 } 3590 break; 3591 3592 case 0x11a: 3593 modrm = x86_ldub_code(env, s); 3594 if (s->flags & HF_MPX_EN_MASK) { 3595 mod = (modrm >> 6) & 3; 3596 reg = ((modrm >> 3) & 7) | REX_R(s); 3597 if (prefixes & PREFIX_REPZ) { 3598 /* bndcl */ 3599 if (reg >= 4 3600 || (prefixes & PREFIX_LOCK) 3601 || s->aflag == MO_16) { 3602 goto illegal_op; 3603 } 3604 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]); 3605 } else if (prefixes & PREFIX_REPNZ) { 3606 /* bndcu */ 3607 if (reg >= 4 3608 || (prefixes & PREFIX_LOCK) 3609 || s->aflag == MO_16) { 3610 goto illegal_op; 3611 } 3612 TCGv_i64 notu = tcg_temp_new_i64(); 3613 tcg_gen_not_i64(notu, cpu_bndu[reg]); 3614 gen_bndck(env, s, modrm, TCG_COND_GTU, notu); 3615 } else if (prefixes & PREFIX_DATA) { 3616 /* bndmov -- from reg/mem */ 3617 if (reg >= 4 || s->aflag == MO_16) { 3618 goto illegal_op; 3619 } 3620 if (mod == 3) { 3621 int reg2 = (modrm & 7) | REX_B(s); 3622 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 3623 goto illegal_op; 3624 } 3625 if (s->flags & HF_MPX_IU_MASK) { 3626 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]); 3627 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]); 3628 } 3629 } else { 3630 gen_lea_modrm(env, s, modrm); 3631 if (CODE64(s)) { 3632 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 3633 s->mem_index, MO_LEUQ); 3634 tcg_gen_addi_tl(s->A0, s->A0, 8); 3635 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 3636 s->mem_index, MO_LEUQ); 3637 } else { 3638 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, 3639 s->mem_index, MO_LEUL); 3640 tcg_gen_addi_tl(s->A0, s->A0, 4); 3641 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, 3642 s->mem_index, MO_LEUL); 3643 } 3644 /* bnd registers are now in-use */ 3645 gen_set_hflag(s, HF_MPX_IU_MASK); 3646 } 3647 } else if (mod != 3) { 3648 /* bndldx */ 3649 AddressParts a = gen_lea_modrm_0(env, s, modrm, false); 3650 if (reg >= 4 3651 || (prefixes & PREFIX_LOCK) 3652 || s->aflag == MO_16 3653 || a.base < -1) { 3654 goto illegal_op; 3655 } 3656 if (a.base >= 0) { 3657 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 3658 } else { 3659 tcg_gen_movi_tl(s->A0, 0); 3660 } 3661 gen_lea_v_seg(s, s->A0, a.def_seg, s->override); 3662 if (a.index >= 0) { 3663 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 3664 } else { 3665 tcg_gen_movi_tl(s->T0, 0); 3666 } 3667 if (CODE64(s)) { 3668 gen_helper_bndldx64(cpu_bndl[reg], tcg_env, s->A0, s->T0); 3669 tcg_gen_ld_i64(cpu_bndu[reg], tcg_env, 3670 offsetof(CPUX86State, mmx_t0.MMX_Q(0))); 3671 } else { 3672 gen_helper_bndldx32(cpu_bndu[reg], tcg_env, s->A0, s->T0); 3673 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]); 3674 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32); 3675 } 3676 gen_set_hflag(s, HF_MPX_IU_MASK); 3677 } 3678 } 3679 gen_nop_modrm(env, s, modrm); 3680 break; 3681 case 0x11b: 3682 modrm = x86_ldub_code(env, s); 3683 if (s->flags & HF_MPX_EN_MASK) { 3684 mod = (modrm >> 6) & 3; 3685 reg = ((modrm >> 3) & 7) | REX_R(s); 3686 if (mod != 3 && (prefixes & PREFIX_REPZ)) { 3687 /* bndmk */ 3688 if (reg >= 4 3689 || (prefixes & PREFIX_LOCK) 3690 || s->aflag == MO_16) { 3691 goto illegal_op; 3692 } 3693 AddressParts a = gen_lea_modrm_0(env, s, modrm, false); 3694 if (a.base >= 0) { 3695 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]); 3696 if (!CODE64(s)) { 3697 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]); 3698 } 3699 } else if (a.base == -1) { 3700 /* no base register has lower bound of 0 */ 3701 tcg_gen_movi_i64(cpu_bndl[reg], 0); 3702 } else { 3703 /* rip-relative generates #ud */ 3704 goto illegal_op; 3705 } 3706 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false)); 3707 if (!CODE64(s)) { 3708 tcg_gen_ext32u_tl(s->A0, s->A0); 3709 } 3710 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0); 3711 /* bnd registers are now in-use */ 3712 gen_set_hflag(s, HF_MPX_IU_MASK); 3713 break; 3714 } else if (prefixes & PREFIX_REPNZ) { 3715 /* bndcn */ 3716 if (reg >= 4 3717 || (prefixes & PREFIX_LOCK) 3718 || s->aflag == MO_16) { 3719 goto illegal_op; 3720 } 3721 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]); 3722 } else if (prefixes & PREFIX_DATA) { 3723 /* bndmov -- to reg/mem */ 3724 if (reg >= 4 || s->aflag == MO_16) { 3725 goto illegal_op; 3726 } 3727 if (mod == 3) { 3728 int reg2 = (modrm & 7) | REX_B(s); 3729 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) { 3730 goto illegal_op; 3731 } 3732 if (s->flags & HF_MPX_IU_MASK) { 3733 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]); 3734 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]); 3735 } 3736 } else { 3737 gen_lea_modrm(env, s, modrm); 3738 if (CODE64(s)) { 3739 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 3740 s->mem_index, MO_LEUQ); 3741 tcg_gen_addi_tl(s->A0, s->A0, 8); 3742 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 3743 s->mem_index, MO_LEUQ); 3744 } else { 3745 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, 3746 s->mem_index, MO_LEUL); 3747 tcg_gen_addi_tl(s->A0, s->A0, 4); 3748 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, 3749 s->mem_index, MO_LEUL); 3750 } 3751 } 3752 } else if (mod != 3) { 3753 /* bndstx */ 3754 AddressParts a = gen_lea_modrm_0(env, s, modrm, false); 3755 if (reg >= 4 3756 || (prefixes & PREFIX_LOCK) 3757 || s->aflag == MO_16 3758 || a.base < -1) { 3759 goto illegal_op; 3760 } 3761 if (a.base >= 0) { 3762 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp); 3763 } else { 3764 tcg_gen_movi_tl(s->A0, 0); 3765 } 3766 gen_lea_v_seg(s, s->A0, a.def_seg, s->override); 3767 if (a.index >= 0) { 3768 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]); 3769 } else { 3770 tcg_gen_movi_tl(s->T0, 0); 3771 } 3772 if (CODE64(s)) { 3773 gen_helper_bndstx64(tcg_env, s->A0, s->T0, 3774 cpu_bndl[reg], cpu_bndu[reg]); 3775 } else { 3776 gen_helper_bndstx32(tcg_env, s->A0, s->T0, 3777 cpu_bndl[reg], cpu_bndu[reg]); 3778 } 3779 } 3780 } 3781 gen_nop_modrm(env, s, modrm); 3782 break; 3783 default: 3784 g_assert_not_reached(); 3785 } 3786 return; 3787 illegal_op: 3788 gen_illegal_opcode(s); 3789 return; 3790 unknown_op: 3791 gen_unknown_opcode(env, s); 3792 } 3793 3794 #include "decode-new.h" 3795 #include "emit.c.inc" 3796 #include "decode-new.c.inc" 3797 3798 void tcg_x86_init(void) 3799 { 3800 static const char reg_names[CPU_NB_REGS][4] = { 3801 #ifdef TARGET_X86_64 3802 [R_EAX] = "rax", 3803 [R_EBX] = "rbx", 3804 [R_ECX] = "rcx", 3805 [R_EDX] = "rdx", 3806 [R_ESI] = "rsi", 3807 [R_EDI] = "rdi", 3808 [R_EBP] = "rbp", 3809 [R_ESP] = "rsp", 3810 [8] = "r8", 3811 [9] = "r9", 3812 [10] = "r10", 3813 [11] = "r11", 3814 [12] = "r12", 3815 [13] = "r13", 3816 [14] = "r14", 3817 [15] = "r15", 3818 #else 3819 [R_EAX] = "eax", 3820 [R_EBX] = "ebx", 3821 [R_ECX] = "ecx", 3822 [R_EDX] = "edx", 3823 [R_ESI] = "esi", 3824 [R_EDI] = "edi", 3825 [R_EBP] = "ebp", 3826 [R_ESP] = "esp", 3827 #endif 3828 }; 3829 static const char eip_name[] = { 3830 #ifdef TARGET_X86_64 3831 "rip" 3832 #else 3833 "eip" 3834 #endif 3835 }; 3836 static const char seg_base_names[6][8] = { 3837 [R_CS] = "cs_base", 3838 [R_DS] = "ds_base", 3839 [R_ES] = "es_base", 3840 [R_FS] = "fs_base", 3841 [R_GS] = "gs_base", 3842 [R_SS] = "ss_base", 3843 }; 3844 static const char bnd_regl_names[4][8] = { 3845 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb" 3846 }; 3847 static const char bnd_regu_names[4][8] = { 3848 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" 3849 }; 3850 int i; 3851 3852 cpu_cc_op = tcg_global_mem_new_i32(tcg_env, 3853 offsetof(CPUX86State, cc_op), "cc_op"); 3854 cpu_cc_dst = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_dst), 3855 "cc_dst"); 3856 cpu_cc_src = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src), 3857 "cc_src"); 3858 cpu_cc_src2 = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src2), 3859 "cc_src2"); 3860 cpu_eip = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, eip), eip_name); 3861 3862 for (i = 0; i < CPU_NB_REGS; ++i) { 3863 cpu_regs[i] = tcg_global_mem_new(tcg_env, 3864 offsetof(CPUX86State, regs[i]), 3865 reg_names[i]); 3866 } 3867 3868 for (i = 0; i < 6; ++i) { 3869 cpu_seg_base[i] 3870 = tcg_global_mem_new(tcg_env, 3871 offsetof(CPUX86State, segs[i].base), 3872 seg_base_names[i]); 3873 } 3874 3875 for (i = 0; i < 4; ++i) { 3876 cpu_bndl[i] 3877 = tcg_global_mem_new_i64(tcg_env, 3878 offsetof(CPUX86State, bnd_regs[i].lb), 3879 bnd_regl_names[i]); 3880 cpu_bndu[i] 3881 = tcg_global_mem_new_i64(tcg_env, 3882 offsetof(CPUX86State, bnd_regs[i].ub), 3883 bnd_regu_names[i]); 3884 } 3885 } 3886 3887 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 3888 { 3889 DisasContext *dc = container_of(dcbase, DisasContext, base); 3890 CPUX86State *env = cpu_env(cpu); 3891 uint32_t flags = dc->base.tb->flags; 3892 uint32_t cflags = tb_cflags(dc->base.tb); 3893 int cpl = (flags >> HF_CPL_SHIFT) & 3; 3894 int iopl = (flags >> IOPL_SHIFT) & 3; 3895 3896 dc->cs_base = dc->base.tb->cs_base; 3897 dc->pc_save = dc->base.pc_next; 3898 dc->flags = flags; 3899 #ifndef CONFIG_USER_ONLY 3900 dc->cpl = cpl; 3901 dc->iopl = iopl; 3902 #endif 3903 3904 /* We make some simplifying assumptions; validate they're correct. */ 3905 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0)); 3906 g_assert(CPL(dc) == cpl); 3907 g_assert(IOPL(dc) == iopl); 3908 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0)); 3909 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0)); 3910 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0)); 3911 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0)); 3912 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0)); 3913 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0)); 3914 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0)); 3915 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0)); 3916 3917 dc->cc_op = CC_OP_DYNAMIC; 3918 dc->cc_op_dirty = false; 3919 /* select memory access functions */ 3920 dc->mem_index = cpu_mmu_index(cpu, false); 3921 dc->cpuid_features = env->features[FEAT_1_EDX]; 3922 dc->cpuid_ext_features = env->features[FEAT_1_ECX]; 3923 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; 3924 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; 3925 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; 3926 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX]; 3927 dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX]; 3928 dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; 3929 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || 3930 (flags & (HF_RF_MASK | HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); 3931 /* 3932 * If jmp_opt, we want to handle each string instruction individually. 3933 * For icount also disable repz optimization so that each iteration 3934 * is accounted separately. 3935 * 3936 * FIXME: this is messy; it makes REP string instructions a lot less 3937 * efficient than they should be and it gets in the way of correct 3938 * handling of RF (interrupts or traps arriving after any iteration 3939 * of a repeated string instruction but the last should set RF to 1). 3940 * Perhaps it would be more efficient if REP string instructions were 3941 * always at the beginning of the TB, or even their own TB? That 3942 * would even allow accounting up to 64k iterations at once for icount. 3943 */ 3944 dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT); 3945 3946 dc->T0 = tcg_temp_new(); 3947 dc->T1 = tcg_temp_new(); 3948 dc->A0 = tcg_temp_new(); 3949 3950 dc->tmp0 = tcg_temp_new(); 3951 dc->tmp1_i64 = tcg_temp_new_i64(); 3952 dc->tmp2_i32 = tcg_temp_new_i32(); 3953 dc->tmp3_i32 = tcg_temp_new_i32(); 3954 dc->tmp4 = tcg_temp_new(); 3955 dc->cc_srcT = tcg_temp_new(); 3956 } 3957 3958 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) 3959 { 3960 } 3961 3962 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 3963 { 3964 DisasContext *dc = container_of(dcbase, DisasContext, base); 3965 target_ulong pc_arg = dc->base.pc_next; 3966 3967 dc->prev_insn_start = dc->base.insn_start; 3968 dc->prev_insn_end = tcg_last_op(); 3969 if (tb_cflags(dcbase->tb) & CF_PCREL) { 3970 pc_arg &= ~TARGET_PAGE_MASK; 3971 } 3972 tcg_gen_insn_start(pc_arg, dc->cc_op); 3973 } 3974 3975 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 3976 { 3977 DisasContext *dc = container_of(dcbase, DisasContext, base); 3978 bool orig_cc_op_dirty = dc->cc_op_dirty; 3979 CCOp orig_cc_op = dc->cc_op; 3980 target_ulong orig_pc_save = dc->pc_save; 3981 3982 #ifdef TARGET_VSYSCALL_PAGE 3983 /* 3984 * Detect entry into the vsyscall page and invoke the syscall. 3985 */ 3986 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) { 3987 gen_exception(dc, EXCP_VSYSCALL); 3988 dc->base.pc_next = dc->pc + 1; 3989 return; 3990 } 3991 #endif 3992 3993 switch (sigsetjmp(dc->jmpbuf, 0)) { 3994 case 0: 3995 disas_insn(dc, cpu); 3996 break; 3997 case 1: 3998 gen_exception_gpf(dc); 3999 break; 4000 case 2: 4001 /* Restore state that may affect the next instruction. */ 4002 dc->pc = dc->base.pc_next; 4003 /* 4004 * TODO: These save/restore can be removed after the table-based 4005 * decoder is complete; we will be decoding the insn completely 4006 * before any code generation that might affect these variables. 4007 */ 4008 dc->cc_op_dirty = orig_cc_op_dirty; 4009 dc->cc_op = orig_cc_op; 4010 dc->pc_save = orig_pc_save; 4011 /* END TODO */ 4012 dc->base.num_insns--; 4013 tcg_remove_ops_after(dc->prev_insn_end); 4014 dc->base.insn_start = dc->prev_insn_start; 4015 dc->base.is_jmp = DISAS_TOO_MANY; 4016 return; 4017 default: 4018 g_assert_not_reached(); 4019 } 4020 4021 /* 4022 * Instruction decoding completed (possibly with #GP if the 4023 * 15-byte boundary was exceeded). 4024 */ 4025 dc->base.pc_next = dc->pc; 4026 if (dc->base.is_jmp == DISAS_NEXT) { 4027 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) { 4028 /* 4029 * If single step mode, we generate only one instruction and 4030 * generate an exception. 4031 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 4032 * the flag and abort the translation to give the irqs a 4033 * chance to happen. 4034 */ 4035 dc->base.is_jmp = DISAS_EOB_NEXT; 4036 } else if (!is_same_page(&dc->base, dc->base.pc_next)) { 4037 dc->base.is_jmp = DISAS_TOO_MANY; 4038 } 4039 } 4040 } 4041 4042 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 4043 { 4044 DisasContext *dc = container_of(dcbase, DisasContext, base); 4045 4046 switch (dc->base.is_jmp) { 4047 case DISAS_NORETURN: 4048 /* 4049 * Most instructions should not use DISAS_NORETURN, as that suppresses 4050 * the handling of hflags normally done by gen_eob(). We can 4051 * get here: 4052 * - for exception and interrupts 4053 * - for jump optimization (which is disabled by INHIBIT_IRQ/RF/TF) 4054 * - for VMRUN because RF/TF handling for the host is done after vmexit, 4055 * and INHIBIT_IRQ is loaded from the VMCB 4056 * - for HLT/PAUSE/MWAIT to exit the main loop with specific EXCP_* values; 4057 * the helpers handle themselves the tasks normally done by gen_eob(). 4058 */ 4059 break; 4060 case DISAS_TOO_MANY: 4061 gen_update_cc_op(dc); 4062 gen_jmp_rel_csize(dc, 0, 0); 4063 break; 4064 case DISAS_EOB_NEXT: 4065 case DISAS_EOB_INHIBIT_IRQ: 4066 assert(dc->base.pc_next == dc->pc); 4067 gen_update_eip_cur(dc); 4068 /* fall through */ 4069 case DISAS_EOB_ONLY: 4070 case DISAS_EOB_RECHECK_TF: 4071 case DISAS_JUMP: 4072 gen_eob(dc, dc->base.is_jmp); 4073 break; 4074 default: 4075 g_assert_not_reached(); 4076 } 4077 } 4078 4079 static const TranslatorOps i386_tr_ops = { 4080 .init_disas_context = i386_tr_init_disas_context, 4081 .tb_start = i386_tr_tb_start, 4082 .insn_start = i386_tr_insn_start, 4083 .translate_insn = i386_tr_translate_insn, 4084 .tb_stop = i386_tr_tb_stop, 4085 }; 4086 4087 /* generate intermediate code for basic block 'tb'. */ 4088 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns, 4089 vaddr pc, void *host_pc) 4090 { 4091 DisasContext dc; 4092 4093 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); 4094 } 4095