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 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 <stdarg.h> 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <string.h> 23 #include <inttypes.h> 24 #include <signal.h> 25 26 #include "qemu/host-utils.h" 27 #include "cpu.h" 28 #include "disas/disas.h" 29 #include "tcg-op.h" 30 31 #include "helper.h" 32 #define GEN_HELPER 1 33 #include "helper.h" 34 #include "exec/hax.h" 35 36 #ifdef _WIN32 37 #undef grp2 38 #endif 39 40 #define PREFIX_REPZ 0x01 41 #define PREFIX_REPNZ 0x02 42 #define PREFIX_LOCK 0x04 43 #define PREFIX_DATA 0x08 44 #define PREFIX_ADR 0x10 45 #define PREFIX_VEX 0x20 46 47 #ifdef TARGET_X86_64 48 #define X86_64_ONLY(x) x 49 #define X86_64_DEF(...) __VA_ARGS__ 50 #define CODE64(s) ((s)->code64) 51 #define REX_X(s) ((s)->rex_x) 52 #define REX_B(s) ((s)->rex_b) 53 /* XXX: gcc generates push/pop in some opcodes, so we cannot use them */ 54 #if 1 55 #define BUGGY_64(x) NULL 56 #endif 57 #else 58 #define X86_64_ONLY(x) NULL 59 #define X86_64_DEF(...) 60 #define CODE64(s) 0 61 #define REX_X(s) 0 62 #define REX_B(s) 0 63 #endif 64 65 #ifdef TARGET_X86_64 66 # define ctztl ctz64 67 # define clztl clz64 68 #else 69 # define ctztl ctz32 70 # define clztl clz32 71 #endif 72 73 //#define MACRO_TEST 1 74 75 /* global register indexes */ 76 static TCGv_ptr cpu_env; 77 static TCGv cpu_A0, cpu_cc_src, cpu_cc_dst; 78 static TCGv_i32 cpu_cc_op; 79 /* local temps */ 80 static TCGv cpu_T[2], cpu_T3; 81 /* local register indexes (only used inside old micro ops) */ 82 static TCGv cpu_tmp0, cpu_tmp4; 83 static TCGv_ptr cpu_ptr0, cpu_ptr1; 84 static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32; 85 static TCGv_i64 cpu_tmp1_i64; 86 static TCGv cpu_tmp5, cpu_tmp6; 87 88 static uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; 89 90 #include "exec/gen-icount.h" 91 92 #ifdef TARGET_X86_64 93 static int x86_64_hregs; 94 #endif 95 96 typedef struct DisasContext { 97 /* current insn context */ 98 int override; /* -1 if no override */ 99 int prefix; 100 int aflag, dflag; 101 target_ulong pc; /* pc = eip + cs_base */ 102 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU 103 static state change (stop translation) */ 104 /* current block context */ 105 target_ulong cs_base; /* base of CS segment */ 106 int pe; /* protected mode */ 107 int code32; /* 32 bit code segment */ 108 #ifdef TARGET_X86_64 109 int lma; /* long mode active */ 110 int code64; /* 64 bit code segment */ 111 int rex_x, rex_b; 112 #endif 113 int ss32; /* 32 bit stack segment */ 114 CCOp cc_op; /* current CC operation */ 115 bool cc_op_dirty; 116 int addseg; /* non zero if either DS/ES/SS have a non zero base */ 117 int f_st; /* currently unused */ 118 int vm86; /* vm86 mode */ 119 int cpl; 120 int iopl; 121 int tf; /* TF cpu flag */ 122 int singlestep_enabled; /* "hardware" single step enabled */ 123 int jmp_opt; /* use direct block chaining for direct jumps */ 124 int mem_index; /* select memory access functions */ 125 uint64_t flags; /* all execution flags */ 126 struct TranslationBlock *tb; 127 int popl_esp_hack; /* for correct popl with esp base handling */ 128 int rip_offset; /* only used in x86_64, but left for simplicity */ 129 int cpuid_features; 130 int cpuid_ext_features; 131 int cpuid_ext2_features; 132 int cpuid_ext3_features; 133 } DisasContext; 134 135 static void gen_eob(DisasContext *s); 136 static void gen_jmp(DisasContext *s, target_ulong eip); 137 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num); 138 139 /* i386 arith/logic operations */ 140 enum { 141 OP_ADDL, 142 OP_ORL, 143 OP_ADCL, 144 OP_SBBL, 145 OP_ANDL, 146 OP_SUBL, 147 OP_XORL, 148 OP_CMPL, 149 }; 150 151 /* i386 shift ops */ 152 enum { 153 OP_ROL, 154 OP_ROR, 155 OP_RCL, 156 OP_RCR, 157 OP_SHL, 158 OP_SHR, 159 OP_SHL1, /* undocumented */ 160 OP_SAR = 7, 161 }; 162 163 enum { 164 JCC_O, 165 JCC_B, 166 JCC_Z, 167 JCC_BE, 168 JCC_S, 169 JCC_P, 170 JCC_L, 171 JCC_LE, 172 }; 173 174 /* operand size */ 175 enum { 176 OT_BYTE = 0, 177 OT_WORD, 178 OT_LONG, 179 OT_QUAD, 180 }; 181 182 enum { 183 /* I386 int registers */ 184 OR_EAX, /* MUST be even numbered */ 185 OR_ECX, 186 OR_EDX, 187 OR_EBX, 188 OR_ESP, 189 OR_EBP, 190 OR_ESI, 191 OR_EDI, 192 193 OR_TMP0 = 16, /* temporary operand register */ 194 OR_TMP1, 195 OR_A0, /* temporary register used when doing address evaluation */ 196 }; 197 198 enum { 199 USES_CC_DST = 1, 200 USES_CC_SRC = 2, 201 }; 202 203 /* Bit set if the global variable is live after setting CC_OP to X. */ 204 static const uint8_t cc_op_live[CC_OP_NB] = { 205 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC, 206 [CC_OP_EFLAGS] = USES_CC_SRC, 207 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC, 208 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC, 209 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC, 210 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC, 211 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC, 212 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST, 213 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC, 214 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC, 215 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC, 216 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC, 217 }; 218 219 static void set_cc_op(DisasContext *s, CCOp op) 220 { 221 int dead; 222 223 if (s->cc_op == op) { 224 return; 225 } 226 227 /* Discard CC computation that will no longer be used. */ 228 dead = cc_op_live[s->cc_op] & ~cc_op_live[op]; 229 if (dead & USES_CC_DST) { 230 tcg_gen_discard_tl(cpu_cc_dst); 231 } 232 if (dead & USES_CC_SRC) { 233 tcg_gen_discard_tl(cpu_cc_src); 234 } 235 236 s->cc_op = op; 237 /* The DYNAMIC setting is translator only, and should never be 238 stored. Thus we always consider it clean. */ 239 s->cc_op_dirty = (op != CC_OP_DYNAMIC); 240 } 241 242 static void gen_update_cc_op(DisasContext *s) 243 { 244 if (s->cc_op_dirty) { 245 tcg_gen_movi_i32(cpu_cc_op, s->cc_op); 246 s->cc_op_dirty = false; 247 } 248 } 249 250 static inline void gen_op_movl_T0_0(void) 251 { 252 tcg_gen_movi_tl(cpu_T[0], 0); 253 } 254 255 static inline void gen_op_movl_T0_im(int32_t val) 256 { 257 tcg_gen_movi_tl(cpu_T[0], val); 258 } 259 260 static inline void gen_op_movl_T0_imu(uint32_t val) 261 { 262 tcg_gen_movi_tl(cpu_T[0], val); 263 } 264 265 static inline void gen_op_movl_T1_im(int32_t val) 266 { 267 tcg_gen_movi_tl(cpu_T[1], val); 268 } 269 270 static inline void gen_op_movl_T1_imu(uint32_t val) 271 { 272 tcg_gen_movi_tl(cpu_T[1], val); 273 } 274 275 static inline void gen_op_movl_A0_im(uint32_t val) 276 { 277 tcg_gen_movi_tl(cpu_A0, val); 278 } 279 280 #ifdef TARGET_X86_64 281 static inline void gen_op_movq_A0_im(int64_t val) 282 { 283 tcg_gen_movi_tl(cpu_A0, val); 284 } 285 #endif 286 287 static inline void gen_movtl_T0_im(target_ulong val) 288 { 289 tcg_gen_movi_tl(cpu_T[0], val); 290 } 291 292 static inline void gen_movtl_T1_im(target_ulong val) 293 { 294 tcg_gen_movi_tl(cpu_T[1], val); 295 } 296 297 static inline void gen_op_andl_T0_ffff(void) 298 { 299 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff); 300 } 301 302 static inline void gen_op_andl_T0_im(uint32_t val) 303 { 304 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val); 305 } 306 307 static inline void gen_op_movl_T0_T1(void) 308 { 309 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); 310 } 311 312 static inline void gen_op_andl_A0_ffff(void) 313 { 314 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff); 315 } 316 317 #ifdef TARGET_X86_64 318 319 #define NB_OP_SIZES 4 320 321 #else /* !TARGET_X86_64 */ 322 323 #define NB_OP_SIZES 3 324 325 #endif /* !TARGET_X86_64 */ 326 327 #if defined(WORDS_BIGENDIAN) 328 #define REG_B_OFFSET (sizeof(target_ulong) - 1) 329 #define REG_H_OFFSET (sizeof(target_ulong) - 2) 330 #define REG_W_OFFSET (sizeof(target_ulong) - 2) 331 #define REG_L_OFFSET (sizeof(target_ulong) - 4) 332 #define REG_LH_OFFSET (sizeof(target_ulong) - 8) 333 #else 334 #define REG_B_OFFSET 0 335 #define REG_H_OFFSET 1 336 #define REG_W_OFFSET 0 337 #define REG_L_OFFSET 0 338 #define REG_LH_OFFSET 4 339 #endif 340 341 /* In instruction encodings for byte register accesses the 342 * register number usually indicates "low 8 bits of register N"; 343 * however there are some special cases where N 4..7 indicates 344 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return 345 * true for this special case, false otherwise. 346 */ 347 static inline bool byte_reg_is_xH(int reg) 348 { 349 if (reg < 4) { 350 return false; 351 } 352 #ifdef TARGET_X86_64 353 if (reg >= 8 || x86_64_hregs) { 354 return false; 355 } 356 #endif 357 return true; 358 } 359 360 static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0) 361 { 362 switch(ot) { 363 case OT_BYTE: 364 if (!byte_reg_is_xH(reg)) { 365 tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_B_OFFSET); 366 } else { 367 tcg_gen_st8_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg - 4]) + REG_H_OFFSET); 368 } 369 break; 370 case OT_WORD: 371 tcg_gen_st16_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET); 372 break; 373 #ifdef TARGET_X86_64 374 case OT_LONG: 375 tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET); 376 /* high part of register set to zero */ 377 tcg_gen_movi_tl(cpu_tmp0, 0); 378 tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_LH_OFFSET); 379 break; 380 default: 381 case OT_QUAD: 382 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg])); 383 break; 384 #else 385 default: 386 case OT_LONG: 387 tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET); 388 break; 389 #endif 390 } 391 } 392 393 static inline void gen_op_mov_reg_T0(int ot, int reg) 394 { 395 gen_op_mov_reg_v(ot, reg, cpu_T[0]); 396 } 397 398 static inline void gen_op_mov_reg_T1(int ot, int reg) 399 { 400 gen_op_mov_reg_v(ot, reg, cpu_T[1]); 401 } 402 403 static inline void gen_op_mov_reg_A0(int size, int reg) 404 { 405 switch(size) { 406 case OT_BYTE: 407 tcg_gen_st16_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET); 408 break; 409 #ifdef TARGET_X86_64 410 case OT_WORD: 411 tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET); 412 /* high part of register set to zero */ 413 tcg_gen_movi_tl(cpu_tmp0, 0); 414 tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_LH_OFFSET); 415 break; 416 default: 417 case OT_LONG: 418 tcg_gen_st_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg])); 419 break; 420 #else 421 default: 422 case OT_WORD: 423 tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET); 424 break; 425 #endif 426 } 427 } 428 429 static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg) 430 { 431 if (ot == OT_BYTE && byte_reg_is_xH(reg)) { 432 tcg_gen_ld8u_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg - 4]) + REG_H_OFFSET); 433 } else { 434 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg])); 435 } 436 } 437 438 static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg) 439 { 440 gen_op_mov_v_reg(ot, cpu_T[t_index], reg); 441 } 442 443 static inline void gen_op_movl_A0_reg(int reg) 444 { 445 tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET); 446 } 447 448 static inline void gen_op_addl_A0_im(int32_t val) 449 { 450 tcg_gen_addi_tl(cpu_A0, cpu_A0, val); 451 #ifdef TARGET_X86_64 452 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff); 453 #endif 454 } 455 456 #ifdef TARGET_X86_64 457 static inline void gen_op_addq_A0_im(int64_t val) 458 { 459 tcg_gen_addi_tl(cpu_A0, cpu_A0, val); 460 } 461 #endif 462 463 static void gen_add_A0_im(DisasContext *s, int val) 464 { 465 #ifdef TARGET_X86_64 466 if (CODE64(s)) 467 gen_op_addq_A0_im(val); 468 else 469 #endif 470 gen_op_addl_A0_im(val); 471 } 472 473 static inline void gen_op_addl_T0_T1(void) 474 { 475 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 476 } 477 478 static inline void gen_op_jmp_T0(void) 479 { 480 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, eip)); 481 } 482 483 static inline void gen_op_add_reg_im(int size, int reg, int32_t val) 484 { 485 switch(size) { 486 case OT_BYTE: 487 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 488 tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val); 489 tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET); 490 break; 491 case OT_WORD: 492 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 493 tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val); 494 #ifdef TARGET_X86_64 495 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff); 496 #endif 497 tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 498 break; 499 #ifdef TARGET_X86_64 500 case OT_LONG: 501 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 502 tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val); 503 tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 504 break; 505 #endif 506 } 507 } 508 509 static inline void gen_op_add_reg_T0(int size, int reg) 510 { 511 switch(size) { 512 case OT_BYTE: 513 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 514 tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]); 515 tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_W_OFFSET); 516 break; 517 case OT_WORD: 518 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 519 tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]); 520 #ifdef TARGET_X86_64 521 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff); 522 #endif 523 tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 524 break; 525 #ifdef TARGET_X86_64 526 case OT_LONG: 527 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 528 tcg_gen_add_tl(cpu_tmp0, cpu_tmp0, cpu_T[0]); 529 tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 530 break; 531 #endif 532 } 533 } 534 535 static inline void gen_op_addl_A0_reg_sN(int shift, int reg) 536 { 537 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 538 if (shift != 0) 539 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift); 540 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); 541 #ifdef TARGET_X86_64 542 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff); 543 #endif 544 } 545 546 static inline void gen_op_movl_A0_seg(int reg) 547 { 548 tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base) + REG_L_OFFSET); 549 } 550 551 static inline void gen_op_addl_A0_seg(DisasContext *s, int reg) 552 { 553 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base)); 554 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); 555 #ifdef TARGET_X86_64 556 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff); 557 #endif 558 } 559 560 #ifdef TARGET_X86_64 561 static inline void gen_op_movq_A0_seg(int reg) 562 { 563 tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base)); 564 } 565 566 static inline void gen_op_addq_A0_seg(int reg) 567 { 568 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base)); 569 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); 570 } 571 572 static inline void gen_op_movq_A0_reg(int reg) 573 { 574 tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, regs[reg])); 575 } 576 577 static inline void gen_op_addq_A0_reg_sN(int shift, int reg) 578 { 579 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg])); 580 if (shift != 0) 581 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift); 582 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); 583 } 584 #endif 585 586 static inline void gen_op_lds_T0_A0(int idx) 587 { 588 int mem_index = (idx >> 2) - 1; 589 switch(idx & 3) { 590 case OT_BYTE: 591 tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index); 592 break; 593 case OT_WORD: 594 tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index); 595 break; 596 default: 597 case OT_LONG: 598 tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index); 599 break; 600 } 601 } 602 603 static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0) 604 { 605 int mem_index = (idx >> 2) - 1; 606 switch(idx & 3) { 607 case OT_BYTE: 608 tcg_gen_qemu_ld8u(t0, a0, mem_index); 609 break; 610 case OT_WORD: 611 tcg_gen_qemu_ld16u(t0, a0, mem_index); 612 break; 613 case OT_LONG: 614 tcg_gen_qemu_ld32u(t0, a0, mem_index); 615 break; 616 default: 617 case OT_QUAD: 618 /* Should never happen on 32-bit targets. */ 619 #ifdef TARGET_X86_64 620 tcg_gen_qemu_ld64(t0, a0, mem_index); 621 #endif 622 break; 623 } 624 } 625 626 /* XXX: always use ldu or lds */ 627 static inline void gen_op_ld_T0_A0(int idx) 628 { 629 gen_op_ld_v(idx, cpu_T[0], cpu_A0); 630 } 631 632 static inline void gen_op_ldu_T0_A0(int idx) 633 { 634 gen_op_ld_v(idx, cpu_T[0], cpu_A0); 635 } 636 637 static inline void gen_op_ld_T1_A0(int idx) 638 { 639 gen_op_ld_v(idx, cpu_T[1], cpu_A0); 640 } 641 642 static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0) 643 { 644 int mem_index = (idx >> 2) - 1; 645 switch(idx & 3) { 646 case OT_BYTE: 647 tcg_gen_qemu_st8(t0, a0, mem_index); 648 break; 649 case OT_WORD: 650 tcg_gen_qemu_st16(t0, a0, mem_index); 651 break; 652 case OT_LONG: 653 tcg_gen_qemu_st32(t0, a0, mem_index); 654 break; 655 default: 656 case OT_QUAD: 657 /* Should never happen on 32-bit targets. */ 658 #ifdef TARGET_X86_64 659 tcg_gen_qemu_st64(t0, a0, mem_index); 660 #endif 661 break; 662 } 663 } 664 665 static inline void gen_op_st_T0_A0(int idx) 666 { 667 gen_op_st_v(idx, cpu_T[0], cpu_A0); 668 } 669 670 static inline void gen_op_st_T1_A0(int idx) 671 { 672 gen_op_st_v(idx, cpu_T[1], cpu_A0); 673 } 674 675 static inline void gen_jmp_im(target_ulong pc) 676 { 677 tcg_gen_movi_tl(cpu_tmp0, pc); 678 tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, eip)); 679 } 680 681 static inline void gen_string_movl_A0_ESI(DisasContext *s) 682 { 683 int override; 684 685 override = s->override; 686 #ifdef TARGET_X86_64 687 if (s->aflag == 2) { 688 if (override >= 0) { 689 gen_op_movq_A0_seg(override); 690 gen_op_addq_A0_reg_sN(0, R_ESI); 691 } else { 692 gen_op_movq_A0_reg(R_ESI); 693 } 694 } else 695 #endif 696 if (s->aflag) { 697 /* 32 bit address */ 698 if (s->addseg && override < 0) 699 override = R_DS; 700 if (override >= 0) { 701 gen_op_movl_A0_seg(override); 702 gen_op_addl_A0_reg_sN(0, R_ESI); 703 } else { 704 gen_op_movl_A0_reg(R_ESI); 705 } 706 } else { 707 /* 16 address, always override */ 708 if (override < 0) 709 override = R_DS; 710 gen_op_movl_A0_reg(R_ESI); 711 gen_op_andl_A0_ffff(); 712 gen_op_addl_A0_seg(s, override); 713 } 714 } 715 716 static inline void gen_string_movl_A0_EDI(DisasContext *s) 717 { 718 #ifdef TARGET_X86_64 719 if (s->aflag == 2) { 720 gen_op_movq_A0_reg(R_EDI); 721 } else 722 #endif 723 if (s->aflag) { 724 if (s->addseg) { 725 gen_op_movl_A0_seg(R_ES); 726 gen_op_addl_A0_reg_sN(0, R_EDI); 727 } else { 728 gen_op_movl_A0_reg(R_EDI); 729 } 730 } else { 731 gen_op_movl_A0_reg(R_EDI); 732 gen_op_andl_A0_ffff(); 733 gen_op_addl_A0_seg(s, R_ES); 734 } 735 } 736 737 static inline void gen_op_movl_T0_Dshift(int ot) 738 { 739 tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, df)); 740 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot); 741 }; 742 743 static TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign) 744 { 745 switch (size) { 746 case OT_BYTE: 747 if (sign) { 748 tcg_gen_ext8s_tl(dst, src); 749 } else { 750 tcg_gen_ext8u_tl(dst, src); 751 } 752 return dst; 753 case OT_WORD: 754 if (sign) { 755 tcg_gen_ext16s_tl(dst, src); 756 } else { 757 tcg_gen_ext16u_tl(dst, src); 758 } 759 return dst; 760 #ifdef TARGET_X86_64 761 case OT_LONG: 762 if (sign) { 763 tcg_gen_ext32s_tl(dst, src); 764 } else { 765 tcg_gen_ext32u_tl(dst, src); 766 } 767 return dst; 768 #endif 769 default: 770 return src; 771 } 772 } 773 774 static void gen_extu(int ot, TCGv reg) 775 { 776 gen_ext_tl(reg, reg, ot, false); 777 } 778 779 static void gen_exts(int ot, TCGv reg) 780 { 781 gen_ext_tl(reg, reg, ot, true); 782 } 783 784 static inline void gen_op_jnz_ecx(int size, int label1) 785 { 786 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[R_ECX])); 787 gen_extu(size + 1, cpu_tmp0); 788 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1); 789 } 790 791 static inline void gen_op_jz_ecx(int size, int label1) 792 { 793 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[R_ECX])); 794 gen_extu(size + 1, cpu_tmp0); 795 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1); 796 } 797 798 static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n) 799 { 800 switch (ot) { 801 case OT_BYTE: 802 gen_helper_inb(v, n); 803 break; 804 case OT_WORD: 805 gen_helper_inw(v, n); 806 break; 807 case OT_LONG: 808 gen_helper_inl(v, n); 809 break; 810 } 811 } 812 813 static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n) 814 { 815 switch (ot) { 816 case OT_BYTE: 817 gen_helper_outb(v, n); 818 break; 819 case OT_WORD: 820 gen_helper_outw(v, n); 821 break; 822 case OT_LONG: 823 gen_helper_outl(v, n); 824 break; 825 } 826 } 827 828 static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip, 829 uint32_t svm_flags) 830 { 831 int state_saved; 832 target_ulong next_eip; 833 834 state_saved = 0; 835 if (s->pe && (s->cpl > s->iopl || s->vm86)) { 836 gen_update_cc_op(s); 837 gen_jmp_im(cur_eip); 838 state_saved = 1; 839 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 840 switch (ot) { 841 case OT_BYTE: 842 gen_helper_check_iob(cpu_env, cpu_tmp2_i32); 843 break; 844 case OT_WORD: 845 gen_helper_check_iow(cpu_env, cpu_tmp2_i32); 846 break; 847 case OT_LONG: 848 gen_helper_check_iol(cpu_env, cpu_tmp2_i32); 849 break; 850 } 851 } 852 if(s->flags & HF_SVMI_MASK) { 853 if (!state_saved) { 854 gen_update_cc_op(s); 855 gen_jmp_im(cur_eip); 856 state_saved = 1; 857 } 858 svm_flags |= (1 << (4 + ot)); 859 next_eip = s->pc - s->cs_base; 860 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 861 gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32, 862 tcg_const_i32(svm_flags), 863 tcg_const_i32(next_eip - cur_eip)); 864 } 865 } 866 867 static inline void gen_movs(DisasContext *s, int ot) 868 { 869 gen_string_movl_A0_ESI(s); 870 gen_op_ld_T0_A0(ot + s->mem_index); 871 gen_string_movl_A0_EDI(s); 872 gen_op_st_T0_A0(ot + s->mem_index); 873 gen_op_movl_T0_Dshift(ot); 874 gen_op_add_reg_T0(s->aflag, R_ESI); 875 gen_op_add_reg_T0(s->aflag, R_EDI); 876 } 877 878 static void gen_op_update1_cc(void) 879 { 880 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 881 } 882 883 static void gen_op_update2_cc(void) 884 { 885 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]); 886 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 887 } 888 889 static inline void gen_op_cmpl_T0_T1_cc(void) 890 { 891 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]); 892 tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]); 893 } 894 895 static inline void gen_op_testl_T0_T1_cc(void) 896 { 897 tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]); 898 } 899 900 static void gen_op_update_neg_cc(void) 901 { 902 tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]); 903 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 904 } 905 906 /* compute all eflags to cc_src */ 907 static void gen_compute_eflags(DisasContext *s) 908 { 909 if (s->cc_op == CC_OP_EFLAGS) { 910 return; 911 } 912 gen_update_cc_op(s); 913 gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_env, cpu_cc_op); 914 set_cc_op(s, CC_OP_EFLAGS); 915 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32); 916 } 917 918 /* compute eflags.C to reg */ 919 static void gen_compute_eflags_c(DisasContext *s, TCGv reg, bool inv) 920 { 921 TCGv t0, t1; 922 int size; 923 924 switch (s->cc_op) { 925 case CC_OP_SUBB ... CC_OP_SUBQ: 926 /* (DATA_TYPE)(CC_DST + CC_SRC) < (DATA_TYPE)CC_SRC */ 927 size = s->cc_op - CC_OP_SUBB; 928 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false); 929 /* If no temporary was used, be careful not to alias t1 and t0. */ 930 t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg; 931 tcg_gen_add_tl(t0, cpu_cc_dst, cpu_cc_src); 932 gen_extu(size, t0); 933 goto add_sub; 934 935 case CC_OP_ADDB ... CC_OP_ADDQ: 936 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */ 937 size = s->cc_op - CC_OP_ADDB; 938 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false); 939 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false); 940 add_sub: 941 tcg_gen_setcond_tl(inv ? TCG_COND_GEU : TCG_COND_LTU, reg, t0, t1); 942 inv = false; 943 break; 944 945 case CC_OP_SBBB ... CC_OP_SBBQ: 946 /* (DATA_TYPE)(CC_DST + CC_SRC + 1) <= (DATA_TYPE)CC_SRC */ 947 size = s->cc_op - CC_OP_SBBB; 948 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false); 949 if (TCGV_EQUAL(t1, reg) && TCGV_EQUAL(reg, cpu_cc_src)) { 950 tcg_gen_mov_tl(cpu_tmp0, cpu_cc_src); 951 t1 = cpu_tmp0; 952 } 953 954 tcg_gen_add_tl(reg, cpu_cc_dst, cpu_cc_src); 955 tcg_gen_addi_tl(reg, reg, 1); 956 gen_extu(size, reg); 957 t0 = reg; 958 goto adc_sbb; 959 960 case CC_OP_ADCB ... CC_OP_ADCQ: 961 /* (DATA_TYPE)CC_DST <= (DATA_TYPE)CC_SRC */ 962 size = s->cc_op - CC_OP_ADCB; 963 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false); 964 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false); 965 adc_sbb: 966 tcg_gen_setcond_tl(inv ? TCG_COND_GTU : TCG_COND_LEU, reg, t0, t1); 967 inv = false; 968 break; 969 970 case CC_OP_LOGICB ... CC_OP_LOGICQ: 971 tcg_gen_movi_tl(reg, 0); 972 break; 973 974 case CC_OP_INCB ... CC_OP_INCQ: 975 case CC_OP_DECB ... CC_OP_DECQ: 976 if (inv) { 977 tcg_gen_xori_tl(reg, cpu_cc_src, 1); 978 } else { 979 tcg_gen_mov_tl(reg, cpu_cc_src); 980 } 981 inv = false; 982 break; 983 984 case CC_OP_SHLB ... CC_OP_SHLQ: 985 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */ 986 size = s->cc_op - CC_OP_SHLB; 987 tcg_gen_shri_tl(reg, cpu_cc_src, (8 << size) - 1); 988 tcg_gen_andi_tl(reg, reg, 1); 989 break; 990 991 case CC_OP_MULB ... CC_OP_MULQ: 992 tcg_gen_setcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, 993 reg, cpu_cc_src, 0); 994 inv = false; 995 break; 996 997 case CC_OP_EFLAGS: 998 case CC_OP_SARB ... CC_OP_SARQ: 999 /* CC_SRC & 1 */ 1000 tcg_gen_andi_tl(reg, cpu_cc_src, 1); 1001 break; 1002 1003 default: 1004 /* The need to compute only C from CC_OP_DYNAMIC is important 1005 in efficiently implementing e.g. INC at the start of a TB. */ 1006 gen_update_cc_op(s); 1007 gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_env, cpu_cc_op); 1008 tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32); 1009 break; 1010 } 1011 if (inv) { 1012 tcg_gen_xori_tl(reg, reg, 1); 1013 } 1014 } 1015 1016 /* compute eflags.P to reg */ 1017 static void gen_compute_eflags_p(DisasContext *s, TCGv reg) 1018 { 1019 gen_compute_eflags(s); 1020 tcg_gen_shri_tl(reg, cpu_cc_src, 2); 1021 tcg_gen_andi_tl(reg, reg, 1); 1022 } 1023 1024 /* compute eflags.S to reg */ 1025 static void gen_compute_eflags_s(DisasContext *s, TCGv reg, bool inv) 1026 { 1027 switch (s->cc_op) { 1028 case CC_OP_DYNAMIC: 1029 gen_compute_eflags(s); 1030 /* FALLTHRU */ 1031 case CC_OP_EFLAGS: 1032 tcg_gen_shri_tl(reg, cpu_cc_src, 7); 1033 tcg_gen_andi_tl(reg, reg, 1); 1034 if (inv) { 1035 tcg_gen_xori_tl(reg, reg, 1); 1036 } 1037 break; 1038 default: 1039 { 1040 int size = (s->cc_op - CC_OP_ADDB) & 3; 1041 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true); 1042 tcg_gen_setcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, reg, t0, 0); 1043 } 1044 break; 1045 } 1046 } 1047 1048 /* compute eflags.O to reg */ 1049 static void gen_compute_eflags_o(DisasContext *s, TCGv reg) 1050 { 1051 gen_compute_eflags(s); 1052 tcg_gen_shri_tl(reg, cpu_cc_src, 11); 1053 tcg_gen_andi_tl(reg, reg, 1); 1054 } 1055 1056 /* compute eflags.Z to reg */ 1057 static void gen_compute_eflags_z(DisasContext *s, TCGv reg, bool inv) 1058 { 1059 switch (s->cc_op) { 1060 case CC_OP_DYNAMIC: 1061 gen_compute_eflags(s); 1062 /* FALLTHRU */ 1063 case CC_OP_EFLAGS: 1064 tcg_gen_shri_tl(reg, cpu_cc_src, 6); 1065 tcg_gen_andi_tl(reg, reg, 1); 1066 if (inv) { 1067 tcg_gen_xori_tl(reg, reg, 1); 1068 } 1069 break; 1070 default: 1071 { 1072 int size = (s->cc_op - CC_OP_ADDB) & 3; 1073 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false); 1074 tcg_gen_setcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, reg, t0, 0); 1075 } 1076 } 1077 } 1078 1079 static void gen_setcc_slow(DisasContext *s, int jcc_op, TCGv reg, bool inv) 1080 { 1081 assert(!TCGV_EQUAL(reg, cpu_cc_src)); 1082 switch(jcc_op) { 1083 case JCC_O: 1084 gen_compute_eflags_o(s, reg); 1085 break; 1086 case JCC_B: 1087 gen_compute_eflags_c(s, reg, inv); 1088 inv = false; 1089 break; 1090 case JCC_Z: 1091 gen_compute_eflags_z(s, reg, inv); 1092 inv = false; 1093 break; 1094 case JCC_BE: 1095 gen_compute_eflags(s); 1096 tcg_gen_andi_tl(reg, cpu_cc_src, CC_Z | CC_C); 1097 tcg_gen_setcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, reg, reg, 0); 1098 return; 1099 case JCC_S: 1100 gen_compute_eflags_s(s, reg, inv); 1101 inv = false; 1102 break; 1103 case JCC_P: 1104 gen_compute_eflags_p(s, reg); 1105 break; 1106 case JCC_L: 1107 gen_compute_eflags(s); 1108 tcg_gen_shri_tl(reg, cpu_cc_src, 11); /* CC_O */ 1109 tcg_gen_shri_tl(cpu_tmp0, cpu_cc_src, 7); /* CC_S */ 1110 tcg_gen_xor_tl(reg, reg, cpu_tmp0); 1111 tcg_gen_andi_tl(reg, reg, 1); 1112 break; 1113 default: 1114 case JCC_LE: 1115 gen_compute_eflags(s); 1116 tcg_gen_shri_tl(reg, cpu_cc_src, 11); /* CC_O */ 1117 tcg_gen_shri_tl(cpu_tmp4, cpu_cc_src, 7); /* CC_S */ 1118 tcg_gen_shri_tl(cpu_tmp0, cpu_cc_src, 6); /* CC_Z */ 1119 tcg_gen_xor_tl(reg, reg, cpu_tmp4); 1120 tcg_gen_or_tl(reg, reg, cpu_tmp0); 1121 tcg_gen_andi_tl(reg, reg, 1); 1122 break; 1123 } 1124 if (inv) { 1125 tcg_gen_xori_tl(reg, reg, 1); 1126 } 1127 } 1128 1129 /* return true if setcc_slow is not needed (WARNING: must be kept in 1130 sync with gen_jcc1) */ 1131 static int is_fast_jcc_case(DisasContext *s, int b) 1132 { 1133 int jcc_op; 1134 jcc_op = (b >> 1) & 7; 1135 switch(s->cc_op) { 1136 /* we optimize the cmp/jcc case */ 1137 case CC_OP_SUBB: 1138 case CC_OP_SUBW: 1139 case CC_OP_SUBL: 1140 case CC_OP_SUBQ: 1141 if (jcc_op == JCC_O || jcc_op == JCC_P) 1142 goto slow_jcc; 1143 break; 1144 1145 /* some jumps are easy to compute */ 1146 case CC_OP_ADDB: 1147 case CC_OP_ADDW: 1148 case CC_OP_ADDL: 1149 case CC_OP_ADDQ: 1150 1151 case CC_OP_LOGICB: 1152 case CC_OP_LOGICW: 1153 case CC_OP_LOGICL: 1154 case CC_OP_LOGICQ: 1155 1156 case CC_OP_INCB: 1157 case CC_OP_INCW: 1158 case CC_OP_INCL: 1159 case CC_OP_INCQ: 1160 1161 case CC_OP_DECB: 1162 case CC_OP_DECW: 1163 case CC_OP_DECL: 1164 case CC_OP_DECQ: 1165 1166 case CC_OP_SHLB: 1167 case CC_OP_SHLW: 1168 case CC_OP_SHLL: 1169 case CC_OP_SHLQ: 1170 if (jcc_op != JCC_Z && jcc_op != JCC_S) 1171 goto slow_jcc; 1172 break; 1173 default: 1174 slow_jcc: 1175 return 0; 1176 } 1177 return 1; 1178 } 1179 1180 /* generate a conditional jump to label 'l1' according to jump opcode 1181 value 'b'. In the fast case, T0 is guaranted not to be used. */ 1182 static inline void gen_jcc1(DisasContext *s, int b, int l1) 1183 { 1184 int inv, jcc_op, size, cond; 1185 TCGv t0; 1186 1187 inv = b & 1; 1188 jcc_op = (b >> 1) & 7; 1189 1190 switch(s->cc_op) { 1191 /* we optimize the cmp/jcc case */ 1192 case CC_OP_SUBB: 1193 case CC_OP_SUBW: 1194 case CC_OP_SUBL: 1195 case CC_OP_SUBQ: 1196 1197 size = s->cc_op - CC_OP_SUBB; 1198 switch(jcc_op) { 1199 case JCC_Z: 1200 fast_jcc_z: 1201 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, false); 1202 tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1); 1203 break; 1204 case JCC_S: 1205 fast_jcc_s: 1206 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, true); 1207 tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, t0, 0, l1); 1208 break; 1209 1210 case JCC_B: 1211 cond = inv ? TCG_COND_GEU : TCG_COND_LTU; 1212 goto fast_jcc_b; 1213 case JCC_BE: 1214 cond = inv ? TCG_COND_GTU : TCG_COND_LEU; 1215 fast_jcc_b: 1216 tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src); 1217 gen_extu(size, cpu_tmp4); 1218 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false); 1219 tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1); 1220 break; 1221 1222 case JCC_L: 1223 cond = inv ? TCG_COND_GE : TCG_COND_LT; 1224 goto fast_jcc_l; 1225 case JCC_LE: 1226 cond = inv ? TCG_COND_GT : TCG_COND_LE; 1227 fast_jcc_l: 1228 tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src); 1229 gen_exts(size, cpu_tmp4); 1230 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true); 1231 tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1); 1232 break; 1233 1234 default: 1235 goto slow_jcc; 1236 } 1237 break; 1238 1239 /* some jumps are easy to compute */ 1240 case CC_OP_ADDB: 1241 case CC_OP_ADDW: 1242 case CC_OP_ADDL: 1243 case CC_OP_ADDQ: 1244 1245 case CC_OP_ADCB: 1246 case CC_OP_ADCW: 1247 case CC_OP_ADCL: 1248 case CC_OP_ADCQ: 1249 1250 case CC_OP_SBBB: 1251 case CC_OP_SBBW: 1252 case CC_OP_SBBL: 1253 case CC_OP_SBBQ: 1254 1255 case CC_OP_LOGICB: 1256 case CC_OP_LOGICW: 1257 case CC_OP_LOGICL: 1258 case CC_OP_LOGICQ: 1259 1260 case CC_OP_INCB: 1261 case CC_OP_INCW: 1262 case CC_OP_INCL: 1263 case CC_OP_INCQ: 1264 1265 case CC_OP_DECB: 1266 case CC_OP_DECW: 1267 case CC_OP_DECL: 1268 case CC_OP_DECQ: 1269 1270 case CC_OP_SHLB: 1271 case CC_OP_SHLW: 1272 case CC_OP_SHLL: 1273 case CC_OP_SHLQ: 1274 1275 case CC_OP_SARB: 1276 case CC_OP_SARW: 1277 case CC_OP_SARL: 1278 case CC_OP_SARQ: 1279 switch(jcc_op) { 1280 case JCC_Z: 1281 size = (s->cc_op - CC_OP_ADDB) & 3; 1282 goto fast_jcc_z; 1283 case JCC_S: 1284 size = (s->cc_op - CC_OP_ADDB) & 3; 1285 goto fast_jcc_s; 1286 default: 1287 goto slow_jcc; 1288 } 1289 break; 1290 default: 1291 slow_jcc: 1292 gen_setcc_slow(s, jcc_op, cpu_T[0], false); 1293 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, 1294 cpu_T[0], 0, l1); 1295 break; 1296 } 1297 } 1298 1299 /* XXX: does not work with gdbstub "ice" single step - not a 1300 serious problem */ 1301 static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip) 1302 { 1303 int l1, l2; 1304 1305 l1 = gen_new_label(); 1306 l2 = gen_new_label(); 1307 gen_op_jnz_ecx(s->aflag, l1); 1308 gen_set_label(l2); 1309 gen_jmp_tb(s, next_eip, 1); 1310 gen_set_label(l1); 1311 return l2; 1312 } 1313 1314 static inline void gen_stos(DisasContext *s, int ot) 1315 { 1316 gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); 1317 gen_string_movl_A0_EDI(s); 1318 gen_op_st_T0_A0(ot + s->mem_index); 1319 gen_op_movl_T0_Dshift(ot); 1320 gen_op_add_reg_T0(s->aflag, R_EDI); 1321 } 1322 1323 static inline void gen_lods(DisasContext *s, int ot) 1324 { 1325 gen_string_movl_A0_ESI(s); 1326 gen_op_ld_T0_A0(ot + s->mem_index); 1327 gen_op_mov_reg_T0(ot, R_EAX); 1328 gen_op_movl_T0_Dshift(ot); 1329 gen_op_add_reg_T0(s->aflag, R_ESI); 1330 } 1331 1332 static inline void gen_scas(DisasContext *s, int ot) 1333 { 1334 gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); 1335 gen_string_movl_A0_EDI(s); 1336 gen_op_ld_T1_A0(ot + s->mem_index); 1337 gen_op_cmpl_T0_T1_cc(); 1338 gen_op_movl_T0_Dshift(ot); 1339 gen_op_add_reg_T0(s->aflag, R_EDI); 1340 set_cc_op(s, CC_OP_SUBB + ot); 1341 } 1342 1343 static inline void gen_cmps(DisasContext *s, int ot) 1344 { 1345 gen_string_movl_A0_ESI(s); 1346 gen_op_ld_T0_A0(ot + s->mem_index); 1347 gen_string_movl_A0_EDI(s); 1348 gen_op_ld_T1_A0(ot + s->mem_index); 1349 gen_op_cmpl_T0_T1_cc(); 1350 gen_op_movl_T0_Dshift(ot); 1351 gen_op_add_reg_T0(s->aflag, R_ESI); 1352 gen_op_add_reg_T0(s->aflag, R_EDI); 1353 set_cc_op(s, CC_OP_SUBB + ot); 1354 } 1355 1356 static inline void gen_ins(DisasContext *s, int ot) 1357 { 1358 if (use_icount) 1359 gen_io_start(); 1360 gen_string_movl_A0_EDI(s); 1361 /* Note: we must do this dummy write first to be restartable in 1362 case of page fault. */ 1363 gen_op_movl_T0_0(); 1364 gen_op_st_T0_A0(ot + s->mem_index); 1365 gen_op_mov_TN_reg(OT_WORD, 1, R_EDX); 1366 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]); 1367 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); 1368 gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32); 1369 gen_op_st_T0_A0(ot + s->mem_index); 1370 gen_op_movl_T0_Dshift(ot); 1371 gen_op_add_reg_T0(s->aflag, R_EDI); 1372 if (use_icount) 1373 gen_io_end(); 1374 } 1375 1376 static inline void gen_outs(DisasContext *s, int ot) 1377 { 1378 if (use_icount) 1379 gen_io_start(); 1380 gen_string_movl_A0_ESI(s); 1381 gen_op_ld_T0_A0(ot + s->mem_index); 1382 1383 gen_op_mov_TN_reg(OT_WORD, 1, R_EDX); 1384 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]); 1385 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); 1386 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]); 1387 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32); 1388 1389 gen_op_movl_T0_Dshift(ot); 1390 gen_op_add_reg_T0(s->aflag, R_ESI); 1391 if (use_icount) 1392 gen_io_end(); 1393 } 1394 1395 /* same method as Valgrind : we generate jumps to current or next 1396 instruction */ 1397 #define GEN_REPZ(op) \ 1398 static inline void gen_repz_ ## op(DisasContext *s, int ot, \ 1399 target_ulong cur_eip, target_ulong next_eip) \ 1400 { \ 1401 int l2;\ 1402 gen_update_cc_op(s); \ 1403 l2 = gen_jz_ecx_string(s, next_eip); \ 1404 gen_ ## op(s, ot); \ 1405 gen_op_add_reg_im(s->aflag, R_ECX, -1); \ 1406 /* a loop would cause two single step exceptions if ECX = 1 \ 1407 before rep string_insn */ \ 1408 if (!s->jmp_opt) \ 1409 gen_op_jz_ecx(s->aflag, l2); \ 1410 gen_jmp(s, cur_eip); \ 1411 } 1412 1413 #define GEN_REPZ2(op) \ 1414 static inline void gen_repz_ ## op(DisasContext *s, int ot, \ 1415 target_ulong cur_eip, \ 1416 target_ulong next_eip, \ 1417 int nz) \ 1418 { \ 1419 int l2;\ 1420 gen_update_cc_op(s); \ 1421 l2 = gen_jz_ecx_string(s, next_eip); \ 1422 gen_ ## op(s, ot); \ 1423 gen_op_add_reg_im(s->aflag, R_ECX, -1); \ 1424 gen_update_cc_op(s); \ 1425 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \ 1426 if (!s->jmp_opt) \ 1427 gen_op_jz_ecx(s->aflag, l2); \ 1428 gen_jmp(s, cur_eip); \ 1429 } 1430 1431 GEN_REPZ(movs) 1432 GEN_REPZ(stos) 1433 GEN_REPZ(lods) 1434 GEN_REPZ(ins) 1435 GEN_REPZ(outs) 1436 GEN_REPZ2(scas) 1437 GEN_REPZ2(cmps) 1438 1439 static void gen_helper_fp_arith_ST0_FT0(int op) 1440 { 1441 switch (op) { 1442 case 0: 1443 gen_helper_fadd_ST0_FT0(cpu_env); 1444 break; 1445 case 1: 1446 gen_helper_fmul_ST0_FT0(cpu_env); 1447 break; 1448 case 2: 1449 gen_helper_fcom_ST0_FT0(cpu_env); 1450 break; 1451 case 3: 1452 gen_helper_fcom_ST0_FT0(cpu_env); 1453 break; 1454 case 4: 1455 gen_helper_fsub_ST0_FT0(cpu_env); 1456 break; 1457 case 5: 1458 gen_helper_fsubr_ST0_FT0(cpu_env); 1459 break; 1460 case 6: 1461 gen_helper_fdiv_ST0_FT0(cpu_env); 1462 break; 1463 case 7: 1464 gen_helper_fdivr_ST0_FT0(cpu_env); 1465 break; 1466 } 1467 } 1468 1469 /* NOTE the exception in "r" op ordering */ 1470 static void gen_helper_fp_arith_STN_ST0(int op, int opreg) 1471 { 1472 TCGv_i32 tmp = tcg_const_i32(opreg); 1473 switch (op) { 1474 case 0: 1475 gen_helper_fadd_STN_ST0(cpu_env, tmp); 1476 break; 1477 case 1: 1478 gen_helper_fmul_STN_ST0(cpu_env, tmp); 1479 break; 1480 case 4: 1481 gen_helper_fsubr_STN_ST0(cpu_env, tmp); 1482 break; 1483 case 5: 1484 gen_helper_fsub_STN_ST0(cpu_env, tmp); 1485 break; 1486 case 6: 1487 gen_helper_fdivr_STN_ST0(cpu_env, tmp); 1488 break; 1489 case 7: 1490 gen_helper_fdiv_STN_ST0(cpu_env, tmp); 1491 break; 1492 } 1493 } 1494 1495 /* if d == OR_TMP0, it means memory operand (address in A0) */ 1496 static void gen_op(DisasContext *s1, int op, int ot, int d) 1497 { 1498 if (d != OR_TMP0) { 1499 gen_op_mov_TN_reg(ot, 0, d); 1500 } else { 1501 gen_op_ld_T0_A0(ot + s1->mem_index); 1502 } 1503 switch(op) { 1504 case OP_ADCL: 1505 gen_compute_eflags_c(s1, cpu_tmp4, false); 1506 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1507 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4); 1508 if (d != OR_TMP0) 1509 gen_op_mov_reg_T0(ot, d); 1510 else 1511 gen_op_st_T0_A0(ot + s1->mem_index); 1512 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]); 1513 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 1514 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4); 1515 tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2); 1516 tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_ADDB + ot); 1517 set_cc_op(s1, CC_OP_DYNAMIC); 1518 break; 1519 case OP_SBBL: 1520 gen_compute_eflags_c(s1, cpu_tmp4, false); 1521 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1522 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4); 1523 if (d != OR_TMP0) 1524 gen_op_mov_reg_T0(ot, d); 1525 else 1526 gen_op_st_T0_A0(ot + s1->mem_index); 1527 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]); 1528 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 1529 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4); 1530 tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2); 1531 tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_SUBB + ot); 1532 set_cc_op(s1, CC_OP_DYNAMIC); 1533 break; 1534 case OP_ADDL: 1535 gen_op_addl_T0_T1(); 1536 if (d != OR_TMP0) 1537 gen_op_mov_reg_T0(ot, d); 1538 else 1539 gen_op_st_T0_A0(ot + s1->mem_index); 1540 gen_op_update2_cc(); 1541 set_cc_op(s1, CC_OP_ADDB + ot); 1542 break; 1543 case OP_SUBL: 1544 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1545 if (d != OR_TMP0) 1546 gen_op_mov_reg_T0(ot, d); 1547 else 1548 gen_op_st_T0_A0(ot + s1->mem_index); 1549 gen_op_update2_cc(); 1550 set_cc_op(s1, CC_OP_SUBB + ot); 1551 break; 1552 default: 1553 case OP_ANDL: 1554 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1555 if (d != OR_TMP0) 1556 gen_op_mov_reg_T0(ot, d); 1557 else 1558 gen_op_st_T0_A0(ot + s1->mem_index); 1559 gen_op_update1_cc(); 1560 set_cc_op(s1, CC_OP_LOGICB + ot); 1561 break; 1562 case OP_ORL: 1563 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1564 if (d != OR_TMP0) 1565 gen_op_mov_reg_T0(ot, d); 1566 else 1567 gen_op_st_T0_A0(ot + s1->mem_index); 1568 gen_op_update1_cc(); 1569 set_cc_op(s1, CC_OP_LOGICB + ot); 1570 break; 1571 case OP_XORL: 1572 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1573 if (d != OR_TMP0) 1574 gen_op_mov_reg_T0(ot, d); 1575 else 1576 gen_op_st_T0_A0(ot + s1->mem_index); 1577 gen_op_update1_cc(); 1578 set_cc_op(s1, CC_OP_LOGICB + ot); 1579 break; 1580 case OP_CMPL: 1581 gen_op_cmpl_T0_T1_cc(); 1582 set_cc_op(s1, CC_OP_SUBB + ot); 1583 break; 1584 } 1585 } 1586 1587 /* if d == OR_TMP0, it means memory operand (address in A0) */ 1588 static void gen_inc(DisasContext *s1, int ot, int d, int c) 1589 { 1590 if (d != OR_TMP0) 1591 gen_op_mov_TN_reg(ot, 0, d); 1592 else 1593 gen_op_ld_T0_A0(ot + s1->mem_index); 1594 gen_compute_eflags_c(s1, cpu_cc_src, false); 1595 if (c > 0) { 1596 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1); 1597 set_cc_op(s1, CC_OP_INCB + ot); 1598 } else { 1599 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1); 1600 set_cc_op(s1, CC_OP_DECB + ot); 1601 } 1602 if (d != OR_TMP0) 1603 gen_op_mov_reg_T0(ot, d); 1604 else 1605 gen_op_st_T0_A0(ot + s1->mem_index); 1606 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 1607 } 1608 1609 static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 1610 int is_right, int is_arith) 1611 { 1612 target_ulong mask; 1613 int shift_label; 1614 TCGv t0, t1; 1615 1616 if (ot == OT_QUAD) 1617 mask = 0x3f; 1618 else 1619 mask = 0x1f; 1620 1621 /* load */ 1622 if (op1 == OR_TMP0) { 1623 gen_op_ld_T0_A0(ot + s->mem_index); 1624 } else { 1625 gen_op_mov_TN_reg(ot, 0, op1); 1626 } 1627 1628 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask); 1629 1630 tcg_gen_addi_tl(cpu_tmp5, cpu_T[1], -1); 1631 1632 if (is_right) { 1633 if (is_arith) { 1634 gen_exts(ot, cpu_T[0]); 1635 tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5); 1636 tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1637 } else { 1638 gen_extu(ot, cpu_T[0]); 1639 tcg_gen_shr_tl(cpu_T3, cpu_T[0], cpu_tmp5); 1640 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1641 } 1642 } else { 1643 tcg_gen_shl_tl(cpu_T3, cpu_T[0], cpu_tmp5); 1644 tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1645 } 1646 1647 /* store */ 1648 if (op1 == OR_TMP0) { 1649 gen_op_st_T0_A0(ot + s->mem_index); 1650 } else { 1651 gen_op_mov_reg_T0(ot, op1); 1652 } 1653 1654 /* update eflags */ 1655 gen_update_cc_op(s); 1656 1657 /* XXX: inefficient */ 1658 t0 = tcg_temp_local_new(); 1659 t1 = tcg_temp_local_new(); 1660 1661 tcg_gen_mov_tl(t0, cpu_T[0]); 1662 tcg_gen_mov_tl(t1, cpu_T3); 1663 1664 shift_label = gen_new_label(); 1665 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, shift_label); 1666 1667 tcg_gen_mov_tl(cpu_cc_src, t1); 1668 tcg_gen_mov_tl(cpu_cc_dst, t0); 1669 if (is_right) 1670 tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot); 1671 else 1672 tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot); 1673 1674 gen_set_label(shift_label); 1675 set_cc_op(s, CC_OP_DYNAMIC); /* cannot predict flags after */ 1676 1677 tcg_temp_free(t0); 1678 tcg_temp_free(t1); 1679 } 1680 1681 static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2, 1682 int is_right, int is_arith) 1683 { 1684 int mask = (ot == OT_QUAD ? 0x3f : 0x1f); 1685 1686 /* load */ 1687 if (op1 == OR_TMP0) 1688 gen_op_ld_T0_A0(ot + s->mem_index); 1689 else 1690 gen_op_mov_TN_reg(ot, 0, op1); 1691 1692 op2 &= mask; 1693 if (op2 != 0) { 1694 if (is_right) { 1695 if (is_arith) { 1696 gen_exts(ot, cpu_T[0]); 1697 tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1); 1698 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2); 1699 } else { 1700 gen_extu(ot, cpu_T[0]); 1701 tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1); 1702 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2); 1703 } 1704 } else { 1705 tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1); 1706 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2); 1707 } 1708 } 1709 1710 /* store */ 1711 if (op1 == OR_TMP0) 1712 gen_op_st_T0_A0(ot + s->mem_index); 1713 else 1714 gen_op_mov_reg_T0(ot, op1); 1715 1716 /* update eflags if non zero shift */ 1717 if (op2 != 0) { 1718 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4); 1719 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 1720 if (is_right) 1721 set_cc_op(s, CC_OP_SARB + ot); 1722 else 1723 set_cc_op(s, CC_OP_SHLB + ot); 1724 } 1725 } 1726 1727 static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2) 1728 { 1729 if (arg2 >= 0) 1730 tcg_gen_shli_tl(ret, arg1, arg2); 1731 else 1732 tcg_gen_shri_tl(ret, arg1, -arg2); 1733 } 1734 1735 static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, int is_right) 1736 { 1737 target_ulong mask; 1738 int label1, label2, data_bits; 1739 TCGv t0, t1, t2, a0; 1740 1741 /* XXX: inefficient, but we must use local temps */ 1742 t0 = tcg_temp_local_new(); 1743 t1 = tcg_temp_local_new(); 1744 t2 = tcg_temp_local_new(); 1745 a0 = tcg_temp_local_new(); 1746 1747 if (ot == OT_QUAD) 1748 mask = 0x3f; 1749 else 1750 mask = 0x1f; 1751 1752 /* load */ 1753 if (op1 == OR_TMP0) { 1754 tcg_gen_mov_tl(a0, cpu_A0); 1755 gen_op_ld_v(ot + s->mem_index, t0, a0); 1756 } else { 1757 gen_op_mov_v_reg(ot, t0, op1); 1758 } 1759 1760 tcg_gen_mov_tl(t1, cpu_T[1]); 1761 1762 tcg_gen_andi_tl(t1, t1, mask); 1763 1764 /* Must test zero case to avoid using undefined behaviour in TCG 1765 shifts. */ 1766 label1 = gen_new_label(); 1767 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1); 1768 1769 if (ot <= OT_WORD) 1770 tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1); 1771 else 1772 tcg_gen_mov_tl(cpu_tmp0, t1); 1773 1774 gen_extu(ot, t0); 1775 tcg_gen_mov_tl(t2, t0); 1776 1777 data_bits = 8 << ot; 1778 /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX: 1779 fix TCG definition) */ 1780 if (is_right) { 1781 tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0); 1782 tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(data_bits), cpu_tmp0); 1783 tcg_gen_shl_tl(t0, t0, cpu_tmp0); 1784 } else { 1785 tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0); 1786 tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(data_bits), cpu_tmp0); 1787 tcg_gen_shr_tl(t0, t0, cpu_tmp0); 1788 } 1789 tcg_gen_or_tl(t0, t0, cpu_tmp4); 1790 1791 gen_set_label(label1); 1792 /* store */ 1793 if (op1 == OR_TMP0) { 1794 gen_op_st_v(ot + s->mem_index, t0, a0); 1795 } else { 1796 gen_op_mov_reg_v(ot, op1, t0); 1797 } 1798 1799 /* update eflags. It is needed anyway most of the time, do it always. */ 1800 gen_compute_eflags(s); 1801 assert(s->cc_op == CC_OP_EFLAGS); 1802 1803 label2 = gen_new_label(); 1804 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2); 1805 1806 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C)); 1807 tcg_gen_xor_tl(cpu_tmp0, t2, t0); 1808 tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1)); 1809 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O); 1810 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0); 1811 if (is_right) { 1812 tcg_gen_shri_tl(t0, t0, data_bits - 1); 1813 } 1814 tcg_gen_andi_tl(t0, t0, CC_C); 1815 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0); 1816 1817 gen_set_label(label2); 1818 1819 tcg_temp_free(t0); 1820 tcg_temp_free(t1); 1821 tcg_temp_free(t2); 1822 tcg_temp_free(a0); 1823 } 1824 1825 static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2, 1826 int is_right) 1827 { 1828 int mask; 1829 int data_bits; 1830 TCGv t0, t1, a0; 1831 1832 /* XXX: inefficient, but we must use local temps */ 1833 t0 = tcg_temp_local_new(); 1834 t1 = tcg_temp_local_new(); 1835 a0 = tcg_temp_local_new(); 1836 1837 if (ot == OT_QUAD) 1838 mask = 0x3f; 1839 else 1840 mask = 0x1f; 1841 1842 /* load */ 1843 if (op1 == OR_TMP0) { 1844 tcg_gen_mov_tl(a0, cpu_A0); 1845 gen_op_ld_v(ot + s->mem_index, t0, a0); 1846 } else { 1847 gen_op_mov_v_reg(ot, t0, op1); 1848 } 1849 1850 gen_extu(ot, t0); 1851 tcg_gen_mov_tl(t1, t0); 1852 1853 op2 &= mask; 1854 data_bits = 8 << ot; 1855 if (op2 != 0) { 1856 int shift = op2 & ((1 << (3 + ot)) - 1); 1857 if (is_right) { 1858 tcg_gen_shri_tl(cpu_tmp4, t0, shift); 1859 tcg_gen_shli_tl(t0, t0, data_bits - shift); 1860 } 1861 else { 1862 tcg_gen_shli_tl(cpu_tmp4, t0, shift); 1863 tcg_gen_shri_tl(t0, t0, data_bits - shift); 1864 } 1865 tcg_gen_or_tl(t0, t0, cpu_tmp4); 1866 } 1867 1868 /* store */ 1869 if (op1 == OR_TMP0) { 1870 gen_op_st_v(ot + s->mem_index, t0, a0); 1871 } else { 1872 gen_op_mov_reg_v(ot, op1, t0); 1873 } 1874 1875 if (op2 != 0) { 1876 /* update eflags */ 1877 gen_compute_eflags(s); 1878 assert(s->cc_op == CC_OP_EFLAGS); 1879 1880 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C)); 1881 tcg_gen_xor_tl(cpu_tmp0, t1, t0); 1882 tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1)); 1883 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O); 1884 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0); 1885 if (is_right) { 1886 tcg_gen_shri_tl(t0, t0, data_bits - 1); 1887 } 1888 tcg_gen_andi_tl(t0, t0, CC_C); 1889 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0); 1890 1891 tcg_gen_discard_tl(cpu_cc_dst); 1892 tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS); 1893 } 1894 1895 tcg_temp_free(t0); 1896 tcg_temp_free(t1); 1897 tcg_temp_free(a0); 1898 } 1899 1900 /* XXX: add faster immediate = 1 case */ 1901 static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 1902 int is_right) 1903 { 1904 gen_compute_eflags(s); 1905 assert(s->cc_op == CC_OP_EFLAGS); 1906 tcg_gen_discard_tl(cpu_cc_dst); 1907 set_cc_op(s, CC_OP_EFLAGS); 1908 1909 /* load */ 1910 if (op1 == OR_TMP0) 1911 gen_op_ld_T0_A0(ot + s->mem_index); 1912 else 1913 gen_op_mov_TN_reg(ot, 0, op1); 1914 1915 if (is_right) { 1916 switch (ot) { 1917 case OT_BYTE: 1918 gen_helper_rcrb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); 1919 break; 1920 case OT_WORD: 1921 gen_helper_rcrw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); 1922 break; 1923 case OT_LONG: 1924 gen_helper_rcrl(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); 1925 break; 1926 #ifdef TARGET_X86_64 1927 case OT_QUAD: 1928 gen_helper_rcrq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); 1929 break; 1930 #endif 1931 } 1932 } else { 1933 switch (ot) { 1934 case OT_BYTE: 1935 gen_helper_rclb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); 1936 break; 1937 case OT_WORD: 1938 gen_helper_rclw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); 1939 break; 1940 case OT_LONG: 1941 gen_helper_rcll(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); 1942 break; 1943 #ifdef TARGET_X86_64 1944 case OT_QUAD: 1945 gen_helper_rclq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); 1946 break; 1947 #endif 1948 } 1949 } 1950 /* store */ 1951 if (op1 == OR_TMP0) 1952 gen_op_st_T0_A0(ot + s->mem_index); 1953 else 1954 gen_op_mov_reg_T0(ot, op1); 1955 } 1956 1957 /* XXX: add faster immediate case */ 1958 static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, 1959 int is_right) 1960 { 1961 int label1, label2, data_bits; 1962 target_ulong mask; 1963 TCGv t0, t1, t2, a0; 1964 1965 t0 = tcg_temp_local_new(); 1966 t1 = tcg_temp_local_new(); 1967 t2 = tcg_temp_local_new(); 1968 a0 = tcg_temp_local_new(); 1969 1970 if (ot == OT_QUAD) 1971 mask = 0x3f; 1972 else 1973 mask = 0x1f; 1974 1975 /* load */ 1976 if (op1 == OR_TMP0) { 1977 tcg_gen_mov_tl(a0, cpu_A0); 1978 gen_op_ld_v(ot + s->mem_index, t0, a0); 1979 } else { 1980 gen_op_mov_v_reg(ot, t0, op1); 1981 } 1982 1983 tcg_gen_andi_tl(cpu_T3, cpu_T3, mask); 1984 1985 tcg_gen_mov_tl(t1, cpu_T[1]); 1986 tcg_gen_mov_tl(t2, cpu_T3); 1987 1988 /* Must test zero case to avoid using undefined behaviour in TCG 1989 shifts. */ 1990 label1 = gen_new_label(); 1991 tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1); 1992 1993 tcg_gen_addi_tl(cpu_tmp5, t2, -1); 1994 if (ot == OT_WORD) { 1995 /* Note: we implement the Intel behaviour for shift count > 16 */ 1996 if (is_right) { 1997 tcg_gen_andi_tl(t0, t0, 0xffff); 1998 tcg_gen_shli_tl(cpu_tmp0, t1, 16); 1999 tcg_gen_or_tl(t0, t0, cpu_tmp0); 2000 tcg_gen_ext32u_tl(t0, t0); 2001 2002 tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5); 2003 2004 /* only needed if count > 16, but a test would complicate */ 2005 tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2); 2006 tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5); 2007 2008 tcg_gen_shr_tl(t0, t0, t2); 2009 2010 tcg_gen_or_tl(t0, t0, cpu_tmp0); 2011 } else { 2012 /* XXX: not optimal */ 2013 tcg_gen_andi_tl(t0, t0, 0xffff); 2014 tcg_gen_shli_tl(t1, t1, 16); 2015 tcg_gen_or_tl(t1, t1, t0); 2016 tcg_gen_ext32u_tl(t1, t1); 2017 2018 tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5); 2019 tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(32), cpu_tmp5); 2020 tcg_gen_shr_tl(cpu_tmp6, t1, cpu_tmp0); 2021 tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp6); 2022 2023 tcg_gen_shl_tl(t0, t0, t2); 2024 tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), t2); 2025 tcg_gen_shr_tl(t1, t1, cpu_tmp5); 2026 tcg_gen_or_tl(t0, t0, t1); 2027 } 2028 } else { 2029 data_bits = 8 << ot; 2030 if (is_right) { 2031 if (ot == OT_LONG) 2032 tcg_gen_ext32u_tl(t0, t0); 2033 2034 tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5); 2035 2036 tcg_gen_shr_tl(t0, t0, t2); 2037 tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2); 2038 tcg_gen_shl_tl(t1, t1, cpu_tmp5); 2039 tcg_gen_or_tl(t0, t0, t1); 2040 2041 } else { 2042 if (ot == OT_LONG) 2043 tcg_gen_ext32u_tl(t1, t1); 2044 2045 tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5); 2046 2047 tcg_gen_shl_tl(t0, t0, t2); 2048 tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), t2); 2049 tcg_gen_shr_tl(t1, t1, cpu_tmp5); 2050 tcg_gen_or_tl(t0, t0, t1); 2051 } 2052 } 2053 tcg_gen_mov_tl(t1, cpu_tmp4); 2054 2055 gen_set_label(label1); 2056 /* store */ 2057 if (op1 == OR_TMP0) { 2058 gen_op_st_v(ot + s->mem_index, t0, a0); 2059 } else { 2060 gen_op_mov_reg_v(ot, op1, t0); 2061 } 2062 2063 /* update eflags */ 2064 gen_update_cc_op(s); 2065 2066 label2 = gen_new_label(); 2067 tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2); 2068 2069 tcg_gen_mov_tl(cpu_cc_src, t1); 2070 tcg_gen_mov_tl(cpu_cc_dst, t0); 2071 if (is_right) { 2072 tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot); 2073 } else { 2074 tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot); 2075 } 2076 gen_set_label(label2); 2077 set_cc_op(s, CC_OP_DYNAMIC); /* cannot predict flags after */ 2078 2079 tcg_temp_free(t0); 2080 tcg_temp_free(t1); 2081 tcg_temp_free(t2); 2082 tcg_temp_free(a0); 2083 } 2084 2085 static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) 2086 { 2087 if (s != OR_TMP1) 2088 gen_op_mov_TN_reg(ot, 1, s); 2089 switch(op) { 2090 case OP_ROL: 2091 gen_rot_rm_T1(s1, ot, d, 0); 2092 break; 2093 case OP_ROR: 2094 gen_rot_rm_T1(s1, ot, d, 1); 2095 break; 2096 case OP_SHL: 2097 case OP_SHL1: 2098 gen_shift_rm_T1(s1, ot, d, 0, 0); 2099 break; 2100 case OP_SHR: 2101 gen_shift_rm_T1(s1, ot, d, 1, 0); 2102 break; 2103 case OP_SAR: 2104 gen_shift_rm_T1(s1, ot, d, 1, 1); 2105 break; 2106 case OP_RCL: 2107 gen_rotc_rm_T1(s1, ot, d, 0); 2108 break; 2109 case OP_RCR: 2110 gen_rotc_rm_T1(s1, ot, d, 1); 2111 break; 2112 } 2113 } 2114 2115 static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c) 2116 { 2117 switch(op) { 2118 case OP_ROL: 2119 gen_rot_rm_im(s1, ot, d, c, 0); 2120 break; 2121 case OP_ROR: 2122 gen_rot_rm_im(s1, ot, d, c, 1); 2123 break; 2124 case OP_SHL: 2125 case OP_SHL1: 2126 gen_shift_rm_im(s1, ot, d, c, 0, 0); 2127 break; 2128 case OP_SHR: 2129 gen_shift_rm_im(s1, ot, d, c, 1, 0); 2130 break; 2131 case OP_SAR: 2132 gen_shift_rm_im(s1, ot, d, c, 1, 1); 2133 break; 2134 default: 2135 /* currently not optimized */ 2136 gen_op_movl_T1_im(c); 2137 gen_shift(s1, op, ot, d, OR_TMP1); 2138 break; 2139 } 2140 } 2141 2142 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, 2143 int *reg_ptr, int *offset_ptr) 2144 { 2145 target_long disp; 2146 int havesib; 2147 int base; 2148 int index; 2149 int scale; 2150 int opreg; 2151 int mod, rm, code, override, must_add_seg; 2152 2153 override = s->override; 2154 must_add_seg = s->addseg; 2155 if (override >= 0) 2156 must_add_seg = 1; 2157 mod = (modrm >> 6) & 3; 2158 rm = modrm & 7; 2159 2160 if (s->aflag) { 2161 2162 havesib = 0; 2163 base = rm; 2164 index = 0; 2165 scale = 0; 2166 2167 if (base == 4) { 2168 havesib = 1; 2169 code = cpu_ldub_code(env, s->pc++); 2170 scale = (code >> 6) & 3; 2171 index = ((code >> 3) & 7) | REX_X(s); 2172 base = (code & 7); 2173 } 2174 base |= REX_B(s); 2175 2176 switch (mod) { 2177 case 0: 2178 if ((base & 7) == 5) { 2179 base = -1; 2180 disp = (int32_t)cpu_ldl_code(env, s->pc); 2181 s->pc += 4; 2182 if (CODE64(s) && !havesib) { 2183 disp += s->pc + s->rip_offset; 2184 } 2185 } else { 2186 disp = 0; 2187 } 2188 break; 2189 case 1: 2190 disp = (int8_t)cpu_ldub_code(env, s->pc++); 2191 break; 2192 default: 2193 case 2: 2194 disp = cpu_ldl_code(env, s->pc); 2195 s->pc += 4; 2196 break; 2197 } 2198 2199 if (base >= 0) { 2200 /* for correct popl handling with esp */ 2201 if (base == 4 && s->popl_esp_hack) 2202 disp += s->popl_esp_hack; 2203 #ifdef TARGET_X86_64 2204 if (s->aflag == 2) { 2205 gen_op_movq_A0_reg(base); 2206 if (disp != 0) { 2207 gen_op_addq_A0_im(disp); 2208 } 2209 } else 2210 #endif 2211 { 2212 gen_op_movl_A0_reg(base); 2213 if (disp != 0) 2214 gen_op_addl_A0_im(disp); 2215 } 2216 } else { 2217 #ifdef TARGET_X86_64 2218 if (s->aflag == 2) { 2219 gen_op_movq_A0_im(disp); 2220 } else 2221 #endif 2222 { 2223 gen_op_movl_A0_im(disp); 2224 } 2225 } 2226 /* XXX: index == 4 is always invalid */ 2227 if (havesib && (index != 4 || scale != 0)) { 2228 #ifdef TARGET_X86_64 2229 if (s->aflag == 2) { 2230 gen_op_addq_A0_reg_sN(scale, index); 2231 } else 2232 #endif 2233 { 2234 gen_op_addl_A0_reg_sN(scale, index); 2235 } 2236 } 2237 if (must_add_seg) { 2238 if (override < 0) { 2239 if (base == R_EBP || base == R_ESP) 2240 override = R_SS; 2241 else 2242 override = R_DS; 2243 } 2244 #ifdef TARGET_X86_64 2245 if (s->aflag == 2) { 2246 gen_op_addq_A0_seg(override); 2247 } else 2248 #endif 2249 { 2250 gen_op_addl_A0_seg(s, override); 2251 } 2252 } 2253 } else { 2254 switch (mod) { 2255 case 0: 2256 if (rm == 6) { 2257 disp = cpu_lduw_code(env, s->pc); 2258 s->pc += 2; 2259 gen_op_movl_A0_im(disp); 2260 rm = 0; /* avoid SS override */ 2261 goto no_rm; 2262 } else { 2263 disp = 0; 2264 } 2265 break; 2266 case 1: 2267 disp = (int8_t)cpu_ldub_code(env, s->pc++); 2268 break; 2269 default: 2270 case 2: 2271 disp = cpu_lduw_code(env, s->pc); 2272 s->pc += 2; 2273 break; 2274 } 2275 switch(rm) { 2276 case 0: 2277 gen_op_movl_A0_reg(R_EBX); 2278 gen_op_addl_A0_reg_sN(0, R_ESI); 2279 break; 2280 case 1: 2281 gen_op_movl_A0_reg(R_EBX); 2282 gen_op_addl_A0_reg_sN(0, R_EDI); 2283 break; 2284 case 2: 2285 gen_op_movl_A0_reg(R_EBP); 2286 gen_op_addl_A0_reg_sN(0, R_ESI); 2287 break; 2288 case 3: 2289 gen_op_movl_A0_reg(R_EBP); 2290 gen_op_addl_A0_reg_sN(0, R_EDI); 2291 break; 2292 case 4: 2293 gen_op_movl_A0_reg(R_ESI); 2294 break; 2295 case 5: 2296 gen_op_movl_A0_reg(R_EDI); 2297 break; 2298 case 6: 2299 gen_op_movl_A0_reg(R_EBP); 2300 break; 2301 default: 2302 case 7: 2303 gen_op_movl_A0_reg(R_EBX); 2304 break; 2305 } 2306 if (disp != 0) 2307 gen_op_addl_A0_im(disp); 2308 gen_op_andl_A0_ffff(); 2309 no_rm: 2310 if (must_add_seg) { 2311 if (override < 0) { 2312 if (rm == 2 || rm == 3 || rm == 6) 2313 override = R_SS; 2314 else 2315 override = R_DS; 2316 } 2317 gen_op_addl_A0_seg(s, override); 2318 } 2319 } 2320 2321 opreg = OR_A0; 2322 disp = 0; 2323 *reg_ptr = opreg; 2324 *offset_ptr = disp; 2325 } 2326 2327 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm) 2328 { 2329 int mod, rm, base, code; 2330 2331 mod = (modrm >> 6) & 3; 2332 if (mod == 3) 2333 return; 2334 rm = modrm & 7; 2335 2336 if (s->aflag) { 2337 2338 base = rm; 2339 2340 if (base == 4) { 2341 code = cpu_ldub_code(env, s->pc++); 2342 base = (code & 7); 2343 } 2344 2345 switch (mod) { 2346 case 0: 2347 if (base == 5) { 2348 s->pc += 4; 2349 } 2350 break; 2351 case 1: 2352 s->pc++; 2353 break; 2354 default: 2355 case 2: 2356 s->pc += 4; 2357 break; 2358 } 2359 } else { 2360 switch (mod) { 2361 case 0: 2362 if (rm == 6) { 2363 s->pc += 2; 2364 } 2365 break; 2366 case 1: 2367 s->pc++; 2368 break; 2369 default: 2370 case 2: 2371 s->pc += 2; 2372 break; 2373 } 2374 } 2375 } 2376 2377 /* used for LEA and MOV AX, mem */ 2378 static void gen_add_A0_ds_seg(DisasContext *s) 2379 { 2380 int override, must_add_seg; 2381 must_add_seg = s->addseg; 2382 override = R_DS; 2383 if (s->override >= 0) { 2384 override = s->override; 2385 must_add_seg = 1; 2386 } else { 2387 override = R_DS; 2388 } 2389 if (must_add_seg) { 2390 #ifdef TARGET_X86_64 2391 if (CODE64(s)) { 2392 gen_op_addq_A0_seg(override); 2393 } else 2394 #endif 2395 { 2396 gen_op_addl_A0_seg(s, override); 2397 } 2398 } 2399 } 2400 2401 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg == 2402 OR_TMP0 */ 2403 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm, 2404 int ot, int reg, int is_store) 2405 { 2406 int mod, rm, opreg, disp; 2407 2408 mod = (modrm >> 6) & 3; 2409 rm = (modrm & 7) | REX_B(s); 2410 if (mod == 3) { 2411 if (is_store) { 2412 if (reg != OR_TMP0) 2413 gen_op_mov_TN_reg(ot, 0, reg); 2414 gen_op_mov_reg_T0(ot, rm); 2415 } else { 2416 gen_op_mov_TN_reg(ot, 0, rm); 2417 if (reg != OR_TMP0) 2418 gen_op_mov_reg_T0(ot, reg); 2419 } 2420 } else { 2421 gen_lea_modrm(env, s, modrm, &opreg, &disp); 2422 if (is_store) { 2423 if (reg != OR_TMP0) 2424 gen_op_mov_TN_reg(ot, 0, reg); 2425 gen_op_st_T0_A0(ot + s->mem_index); 2426 } else { 2427 gen_op_ld_T0_A0(ot + s->mem_index); 2428 if (reg != OR_TMP0) 2429 gen_op_mov_reg_T0(ot, reg); 2430 } 2431 } 2432 } 2433 2434 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, int ot) 2435 { 2436 uint32_t ret; 2437 2438 switch(ot) { 2439 case OT_BYTE: 2440 ret = cpu_ldub_code(env, s->pc); 2441 s->pc++; 2442 break; 2443 case OT_WORD: 2444 ret = cpu_lduw_code(env, s->pc); 2445 s->pc += 2; 2446 break; 2447 default: 2448 case OT_LONG: 2449 ret = cpu_ldl_code(env, s->pc); 2450 s->pc += 4; 2451 break; 2452 } 2453 return ret; 2454 } 2455 2456 static inline int insn_const_size(unsigned int ot) 2457 { 2458 if (ot <= OT_LONG) 2459 return 1 << ot; 2460 else 2461 return 4; 2462 } 2463 2464 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip) 2465 { 2466 TranslationBlock *tb; 2467 target_ulong pc; 2468 2469 pc = s->cs_base + eip; 2470 tb = s->tb; 2471 /* NOTE: we handle the case where the TB spans two pages here */ 2472 if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) || 2473 (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) { 2474 /* jump to same page: we can use a direct jump */ 2475 tcg_gen_goto_tb(tb_num); 2476 gen_jmp_im(eip); 2477 tcg_gen_exit_tb((uintptr_t)tb + tb_num); 2478 } else { 2479 /* jump to another page: currently not optimized */ 2480 gen_jmp_im(eip); 2481 gen_eob(s); 2482 } 2483 } 2484 2485 static inline void gen_jcc(DisasContext *s, int b, 2486 target_ulong val, target_ulong next_eip) 2487 { 2488 int l1, l2; 2489 2490 if (s->jmp_opt) { 2491 gen_update_cc_op(s); 2492 l1 = gen_new_label(); 2493 gen_jcc1(s, b, l1); 2494 set_cc_op(s, CC_OP_DYNAMIC); 2495 2496 gen_goto_tb(s, 0, next_eip); 2497 2498 gen_set_label(l1); 2499 gen_goto_tb(s, 1, val); 2500 s->is_jmp = 3; 2501 } else { 2502 l1 = gen_new_label(); 2503 l2 = gen_new_label(); 2504 gen_jcc1(s, b, l1); 2505 2506 gen_jmp_im(next_eip); 2507 tcg_gen_br(l2); 2508 2509 gen_set_label(l1); 2510 gen_jmp_im(val); 2511 gen_set_label(l2); 2512 gen_eob(s); 2513 } 2514 } 2515 2516 static void gen_setcc(DisasContext *s, int b) 2517 { 2518 int inv, jcc_op, l1; 2519 TCGv t0; 2520 2521 if (is_fast_jcc_case(s, b)) { 2522 /* nominal case: we use a jump */ 2523 /* XXX: make it faster by adding new instructions in TCG */ 2524 t0 = tcg_temp_local_new(); 2525 tcg_gen_movi_tl(t0, 0); 2526 l1 = gen_new_label(); 2527 gen_jcc1(s, b ^ 1, l1); 2528 tcg_gen_movi_tl(t0, 1); 2529 gen_set_label(l1); 2530 tcg_gen_mov_tl(cpu_T[0], t0); 2531 tcg_temp_free(t0); 2532 } else { 2533 /* slow case: it is more efficient not to generate a jump, 2534 although it is questionnable whether this optimization is 2535 worth to */ 2536 inv = b & 1; 2537 jcc_op = (b >> 1) & 7; 2538 gen_setcc_slow(s, jcc_op, cpu_T[0], inv); 2539 } 2540 } 2541 2542 static inline void gen_op_movl_T0_seg(int seg_reg) 2543 { 2544 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 2545 offsetof(CPUX86State,segs[seg_reg].selector)); 2546 } 2547 2548 static inline void gen_op_movl_seg_T0_vm(int seg_reg) 2549 { 2550 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff); 2551 tcg_gen_st32_tl(cpu_T[0], cpu_env, 2552 offsetof(CPUX86State,segs[seg_reg].selector)); 2553 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4); 2554 tcg_gen_st_tl(cpu_T[0], cpu_env, 2555 offsetof(CPUX86State,segs[seg_reg].base)); 2556 } 2557 2558 /* move T0 to seg_reg and compute if the CPU state may change. Never 2559 call this function with seg_reg == R_CS */ 2560 static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip) 2561 { 2562 if (s->pe && !s->vm86) { 2563 /* XXX: optimize by finding processor state dynamically */ 2564 gen_update_cc_op(s); 2565 gen_jmp_im(cur_eip); 2566 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 2567 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32); 2568 /* abort translation because the addseg value may change or 2569 because ss32 may change. For R_SS, translation must always 2570 stop as a special handling must be done to disable hardware 2571 interrupts for the next instruction */ 2572 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS)) 2573 s->is_jmp = 3; 2574 } else { 2575 gen_op_movl_seg_T0_vm(seg_reg); 2576 if (seg_reg == R_SS) 2577 s->is_jmp = 3; 2578 } 2579 } 2580 2581 static inline int svm_is_rep(int prefixes) 2582 { 2583 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0); 2584 } 2585 2586 static inline void 2587 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start, 2588 uint32_t type, uint64_t param) 2589 { 2590 /* no SVM activated; fast case */ 2591 if (likely(!(s->flags & HF_SVMI_MASK))) 2592 return; 2593 gen_update_cc_op(s); 2594 gen_jmp_im(pc_start - s->cs_base); 2595 gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type), 2596 tcg_const_i64(param)); 2597 } 2598 2599 static inline void 2600 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type) 2601 { 2602 gen_svm_check_intercept_param(s, pc_start, type, 0); 2603 } 2604 2605 static inline void gen_stack_update(DisasContext *s, int addend) 2606 { 2607 #ifdef TARGET_X86_64 2608 if (CODE64(s)) { 2609 gen_op_add_reg_im(2, R_ESP, addend); 2610 } else 2611 #endif 2612 if (s->ss32) { 2613 gen_op_add_reg_im(1, R_ESP, addend); 2614 } else { 2615 gen_op_add_reg_im(0, R_ESP, addend); 2616 } 2617 } 2618 2619 /* generate a push. It depends on ss32, addseg and dflag */ 2620 static void gen_push_T0(DisasContext *s) 2621 { 2622 #ifdef TARGET_X86_64 2623 if (CODE64(s)) { 2624 gen_op_movq_A0_reg(R_ESP); 2625 if (s->dflag) { 2626 gen_op_addq_A0_im(-8); 2627 gen_op_st_T0_A0(OT_QUAD + s->mem_index); 2628 } else { 2629 gen_op_addq_A0_im(-2); 2630 gen_op_st_T0_A0(OT_WORD + s->mem_index); 2631 } 2632 gen_op_mov_reg_A0(2, R_ESP); 2633 } else 2634 #endif 2635 { 2636 gen_op_movl_A0_reg(R_ESP); 2637 if (!s->dflag) 2638 gen_op_addl_A0_im(-2); 2639 else 2640 gen_op_addl_A0_im(-4); 2641 if (s->ss32) { 2642 if (s->addseg) { 2643 tcg_gen_mov_tl(cpu_T[1], cpu_A0); 2644 gen_op_addl_A0_seg(s, R_SS); 2645 } 2646 } else { 2647 gen_op_andl_A0_ffff(); 2648 tcg_gen_mov_tl(cpu_T[1], cpu_A0); 2649 gen_op_addl_A0_seg(s, R_SS); 2650 } 2651 gen_op_st_T0_A0(s->dflag + 1 + s->mem_index); 2652 if (s->ss32 && !s->addseg) 2653 gen_op_mov_reg_A0(1, R_ESP); 2654 else 2655 gen_op_mov_reg_T1(s->ss32 + 1, R_ESP); 2656 } 2657 } 2658 2659 /* generate a push. It depends on ss32, addseg and dflag */ 2660 /* slower version for T1, only used for call Ev */ 2661 static void gen_push_T1(DisasContext *s) 2662 { 2663 #ifdef TARGET_X86_64 2664 if (CODE64(s)) { 2665 gen_op_movq_A0_reg(R_ESP); 2666 if (s->dflag) { 2667 gen_op_addq_A0_im(-8); 2668 gen_op_st_T1_A0(OT_QUAD + s->mem_index); 2669 } else { 2670 gen_op_addq_A0_im(-2); 2671 gen_op_st_T0_A0(OT_WORD + s->mem_index); 2672 } 2673 gen_op_mov_reg_A0(2, R_ESP); 2674 } else 2675 #endif 2676 { 2677 gen_op_movl_A0_reg(R_ESP); 2678 if (!s->dflag) 2679 gen_op_addl_A0_im(-2); 2680 else 2681 gen_op_addl_A0_im(-4); 2682 if (s->ss32) { 2683 if (s->addseg) { 2684 gen_op_addl_A0_seg(s, R_SS); 2685 } 2686 } else { 2687 gen_op_andl_A0_ffff(); 2688 gen_op_addl_A0_seg(s, R_SS); 2689 } 2690 gen_op_st_T1_A0(s->dflag + 1 + s->mem_index); 2691 2692 if (s->ss32 && !s->addseg) 2693 gen_op_mov_reg_A0(1, R_ESP); 2694 else 2695 gen_stack_update(s, (-2) << s->dflag); 2696 } 2697 } 2698 2699 /* two step pop is necessary for precise exceptions */ 2700 static void gen_pop_T0(DisasContext *s) 2701 { 2702 #ifdef TARGET_X86_64 2703 if (CODE64(s)) { 2704 gen_op_movq_A0_reg(R_ESP); 2705 gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index); 2706 } else 2707 #endif 2708 { 2709 gen_op_movl_A0_reg(R_ESP); 2710 if (s->ss32) { 2711 if (s->addseg) 2712 gen_op_addl_A0_seg(s, R_SS); 2713 } else { 2714 gen_op_andl_A0_ffff(); 2715 gen_op_addl_A0_seg(s, R_SS); 2716 } 2717 gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index); 2718 } 2719 } 2720 2721 static void gen_pop_update(DisasContext *s) 2722 { 2723 #ifdef TARGET_X86_64 2724 if (CODE64(s) && s->dflag) { 2725 gen_stack_update(s, 8); 2726 } else 2727 #endif 2728 { 2729 gen_stack_update(s, 2 << s->dflag); 2730 } 2731 } 2732 2733 static void gen_stack_A0(DisasContext *s) 2734 { 2735 gen_op_movl_A0_reg(R_ESP); 2736 if (!s->ss32) 2737 gen_op_andl_A0_ffff(); 2738 tcg_gen_mov_tl(cpu_T[1], cpu_A0); 2739 if (s->addseg) 2740 gen_op_addl_A0_seg(s, R_SS); 2741 } 2742 2743 /* NOTE: wrap around in 16 bit not fully handled */ 2744 static void gen_pusha(DisasContext *s) 2745 { 2746 int i; 2747 gen_op_movl_A0_reg(R_ESP); 2748 gen_op_addl_A0_im(-16 << s->dflag); 2749 if (!s->ss32) 2750 gen_op_andl_A0_ffff(); 2751 tcg_gen_mov_tl(cpu_T[1], cpu_A0); 2752 if (s->addseg) 2753 gen_op_addl_A0_seg(s, R_SS); 2754 for(i = 0;i < 8; i++) { 2755 gen_op_mov_TN_reg(OT_LONG, 0, 7 - i); 2756 gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index); 2757 gen_op_addl_A0_im(2 << s->dflag); 2758 } 2759 gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP); 2760 } 2761 2762 /* NOTE: wrap around in 16 bit not fully handled */ 2763 static void gen_popa(DisasContext *s) 2764 { 2765 int i; 2766 gen_op_movl_A0_reg(R_ESP); 2767 if (!s->ss32) 2768 gen_op_andl_A0_ffff(); 2769 tcg_gen_mov_tl(cpu_T[1], cpu_A0); 2770 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 << s->dflag); 2771 if (s->addseg) 2772 gen_op_addl_A0_seg(s, R_SS); 2773 for(i = 0;i < 8; i++) { 2774 /* ESP is not reloaded */ 2775 if (i != 3) { 2776 gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index); 2777 gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i); 2778 } 2779 gen_op_addl_A0_im(2 << s->dflag); 2780 } 2781 gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP); 2782 } 2783 2784 static void gen_enter(DisasContext *s, int esp_addend, int level) 2785 { 2786 int ot, opsize; 2787 2788 level &= 0x1f; 2789 #ifdef TARGET_X86_64 2790 if (CODE64(s)) { 2791 ot = s->dflag ? OT_QUAD : OT_WORD; 2792 opsize = 1 << ot; 2793 2794 gen_op_movl_A0_reg(R_ESP); 2795 gen_op_addq_A0_im(-opsize); 2796 tcg_gen_mov_tl(cpu_T[1], cpu_A0); 2797 2798 /* push bp */ 2799 gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); 2800 gen_op_st_T0_A0(ot + s->mem_index); 2801 if (level) { 2802 /* XXX: must save state */ 2803 gen_helper_enter64_level(cpu_env, tcg_const_i32(level), 2804 tcg_const_i32((ot == OT_QUAD)), 2805 cpu_T[1]); 2806 } 2807 gen_op_mov_reg_T1(ot, R_EBP); 2808 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level)); 2809 gen_op_mov_reg_T1(OT_QUAD, R_ESP); 2810 } else 2811 #endif 2812 { 2813 ot = s->dflag + OT_WORD; 2814 opsize = 2 << s->dflag; 2815 2816 gen_op_movl_A0_reg(R_ESP); 2817 gen_op_addl_A0_im(-opsize); 2818 if (!s->ss32) 2819 gen_op_andl_A0_ffff(); 2820 tcg_gen_mov_tl(cpu_T[1], cpu_A0); 2821 if (s->addseg) 2822 gen_op_addl_A0_seg(s, R_SS); 2823 /* push bp */ 2824 gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); 2825 gen_op_st_T0_A0(ot + s->mem_index); 2826 if (level) { 2827 /* XXX: must save state */ 2828 gen_helper_enter_level(cpu_env, tcg_const_i32(level), 2829 tcg_const_i32(s->dflag), 2830 cpu_T[1]); 2831 } 2832 gen_op_mov_reg_T1(ot, R_EBP); 2833 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level)); 2834 gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP); 2835 } 2836 } 2837 2838 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip) 2839 { 2840 gen_update_cc_op(s); 2841 gen_jmp_im(cur_eip); 2842 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno)); 2843 s->is_jmp = 3; 2844 } 2845 2846 /* an interrupt is different from an exception because of the 2847 privilege checks */ 2848 static void gen_interrupt(DisasContext *s, int intno, 2849 target_ulong cur_eip, target_ulong next_eip) 2850 { 2851 gen_update_cc_op(s); 2852 gen_jmp_im(cur_eip); 2853 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno), 2854 tcg_const_i32(next_eip - cur_eip)); 2855 s->is_jmp = 3; 2856 } 2857 2858 static void gen_debug(DisasContext *s, target_ulong cur_eip) 2859 { 2860 gen_update_cc_op(s); 2861 gen_jmp_im(cur_eip); 2862 gen_helper_debug(cpu_env); 2863 s->is_jmp = 3; 2864 } 2865 2866 /* generate a generic end of block. Trace exception is also generated 2867 if needed */ 2868 static void gen_eob(DisasContext *s) 2869 { 2870 gen_update_cc_op(s); 2871 if (s->tb->flags & HF_INHIBIT_IRQ_MASK) { 2872 gen_helper_reset_inhibit_irq(cpu_env); 2873 } 2874 if (s->tb->flags & HF_RF_MASK) { 2875 gen_helper_reset_rf(cpu_env); 2876 } 2877 if (s->singlestep_enabled) { 2878 gen_helper_debug(cpu_env); 2879 } else if (s->tf) { 2880 gen_helper_single_step(cpu_env); 2881 } else { 2882 tcg_gen_exit_tb(0); 2883 } 2884 s->is_jmp = 3; 2885 } 2886 2887 /* generate a jump to eip. No segment change must happen before as a 2888 direct call to the next block may occur */ 2889 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num) 2890 { 2891 if (s->jmp_opt) { 2892 gen_update_cc_op(s); 2893 gen_goto_tb(s, tb_num, eip); 2894 s->is_jmp = 3; 2895 } else { 2896 gen_jmp_im(eip); 2897 gen_eob(s); 2898 } 2899 } 2900 2901 static void gen_jmp(DisasContext *s, target_ulong eip) 2902 { 2903 gen_jmp_tb(s, eip, 0); 2904 } 2905 2906 static inline void gen_ldq_env_A0(int idx, int offset) 2907 { 2908 int mem_index = (idx >> 2) - 1; 2909 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index); 2910 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset); 2911 } 2912 2913 static inline void gen_stq_env_A0(int idx, int offset) 2914 { 2915 int mem_index = (idx >> 2) - 1; 2916 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset); 2917 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index); 2918 } 2919 2920 static inline void gen_ldo_env_A0(int idx, int offset) 2921 { 2922 int mem_index = (idx >> 2) - 1; 2923 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index); 2924 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0))); 2925 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8); 2926 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index); 2927 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1))); 2928 } 2929 2930 static inline void gen_sto_env_A0(int idx, int offset) 2931 { 2932 int mem_index = (idx >> 2) - 1; 2933 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0))); 2934 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index); 2935 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8); 2936 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1))); 2937 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index); 2938 } 2939 2940 static inline void gen_op_movo(int d_offset, int s_offset) 2941 { 2942 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset); 2943 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset); 2944 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8); 2945 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8); 2946 } 2947 2948 static inline void gen_op_movq(int d_offset, int s_offset) 2949 { 2950 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset); 2951 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset); 2952 } 2953 2954 static inline void gen_op_movl(int d_offset, int s_offset) 2955 { 2956 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset); 2957 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset); 2958 } 2959 2960 static inline void gen_op_movq_env_0(int d_offset) 2961 { 2962 tcg_gen_movi_i64(cpu_tmp1_i64, 0); 2963 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset); 2964 } 2965 2966 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg); 2967 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg); 2968 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val); 2969 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val); 2970 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b); 2971 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, 2972 TCGv_i32 val); 2973 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val); 2974 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, 2975 TCGv val); 2976 2977 #define SSE_SPECIAL ((void *)1) 2978 #define SSE_DUMMY ((void *)2) 2979 2980 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm } 2981 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \ 2982 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, } 2983 2984 static const SSEFunc_0_epp sse_op_table1[256][4] = { 2985 /* 3DNow! extensions */ 2986 [0x0e] = { SSE_DUMMY }, /* femms */ 2987 [0x0f] = { SSE_DUMMY }, /* pf... */ 2988 /* pure SSE operations */ 2989 [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */ 2990 [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */ 2991 [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */ 2992 [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */ 2993 [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm }, 2994 [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm }, 2995 [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */ 2996 [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */ 2997 2998 [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */ 2999 [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */ 3000 [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */ 3001 [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */ 3002 [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */ 3003 [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */ 3004 [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd }, 3005 [0x2f] = { gen_helper_comiss, gen_helper_comisd }, 3006 [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */ 3007 [0x51] = SSE_FOP(sqrt), 3008 [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL }, 3009 [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL }, 3010 [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */ 3011 [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */ 3012 [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */ 3013 [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */ 3014 [0x58] = SSE_FOP(add), 3015 [0x59] = SSE_FOP(mul), 3016 [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps, 3017 gen_helper_cvtss2sd, gen_helper_cvtsd2ss }, 3018 [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq }, 3019 [0x5c] = SSE_FOP(sub), 3020 [0x5d] = SSE_FOP(min), 3021 [0x5e] = SSE_FOP(div), 3022 [0x5f] = SSE_FOP(max), 3023 3024 [0xc2] = SSE_FOP(cmpeq), 3025 [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps, 3026 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */ 3027 3028 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */ 3029 [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, 3030 [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, 3031 3032 /* MMX ops and their SSE extensions */ 3033 [0x60] = MMX_OP2(punpcklbw), 3034 [0x61] = MMX_OP2(punpcklwd), 3035 [0x62] = MMX_OP2(punpckldq), 3036 [0x63] = MMX_OP2(packsswb), 3037 [0x64] = MMX_OP2(pcmpgtb), 3038 [0x65] = MMX_OP2(pcmpgtw), 3039 [0x66] = MMX_OP2(pcmpgtl), 3040 [0x67] = MMX_OP2(packuswb), 3041 [0x68] = MMX_OP2(punpckhbw), 3042 [0x69] = MMX_OP2(punpckhwd), 3043 [0x6a] = MMX_OP2(punpckhdq), 3044 [0x6b] = MMX_OP2(packssdw), 3045 [0x6c] = { NULL, gen_helper_punpcklqdq_xmm }, 3046 [0x6d] = { NULL, gen_helper_punpckhqdq_xmm }, 3047 [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */ 3048 [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */ 3049 [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx, 3050 (SSEFunc_0_epp)gen_helper_pshufd_xmm, 3051 (SSEFunc_0_epp)gen_helper_pshufhw_xmm, 3052 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */ 3053 [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */ 3054 [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */ 3055 [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */ 3056 [0x74] = MMX_OP2(pcmpeqb), 3057 [0x75] = MMX_OP2(pcmpeqw), 3058 [0x76] = MMX_OP2(pcmpeql), 3059 [0x77] = { SSE_DUMMY }, /* emms */ 3060 [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps }, 3061 [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps }, 3062 [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */ 3063 [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */ 3064 [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */ 3065 [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */ 3066 [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps }, 3067 [0xd1] = MMX_OP2(psrlw), 3068 [0xd2] = MMX_OP2(psrld), 3069 [0xd3] = MMX_OP2(psrlq), 3070 [0xd4] = MMX_OP2(paddq), 3071 [0xd5] = MMX_OP2(pmullw), 3072 [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, 3073 [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */ 3074 [0xd8] = MMX_OP2(psubusb), 3075 [0xd9] = MMX_OP2(psubusw), 3076 [0xda] = MMX_OP2(pminub), 3077 [0xdb] = MMX_OP2(pand), 3078 [0xdc] = MMX_OP2(paddusb), 3079 [0xdd] = MMX_OP2(paddusw), 3080 [0xde] = MMX_OP2(pmaxub), 3081 [0xdf] = MMX_OP2(pandn), 3082 [0xe0] = MMX_OP2(pavgb), 3083 [0xe1] = MMX_OP2(psraw), 3084 [0xe2] = MMX_OP2(psrad), 3085 [0xe3] = MMX_OP2(pavgw), 3086 [0xe4] = MMX_OP2(pmulhuw), 3087 [0xe5] = MMX_OP2(pmulhw), 3088 [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq }, 3089 [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */ 3090 [0xe8] = MMX_OP2(psubsb), 3091 [0xe9] = MMX_OP2(psubsw), 3092 [0xea] = MMX_OP2(pminsw), 3093 [0xeb] = MMX_OP2(por), 3094 [0xec] = MMX_OP2(paddsb), 3095 [0xed] = MMX_OP2(paddsw), 3096 [0xee] = MMX_OP2(pmaxsw), 3097 [0xef] = MMX_OP2(pxor), 3098 [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */ 3099 [0xf1] = MMX_OP2(psllw), 3100 [0xf2] = MMX_OP2(pslld), 3101 [0xf3] = MMX_OP2(psllq), 3102 [0xf4] = MMX_OP2(pmuludq), 3103 [0xf5] = MMX_OP2(pmaddwd), 3104 [0xf6] = MMX_OP2(psadbw), 3105 [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx, 3106 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */ 3107 [0xf8] = MMX_OP2(psubb), 3108 [0xf9] = MMX_OP2(psubw), 3109 [0xfa] = MMX_OP2(psubl), 3110 [0xfb] = MMX_OP2(psubq), 3111 [0xfc] = MMX_OP2(paddb), 3112 [0xfd] = MMX_OP2(paddw), 3113 [0xfe] = MMX_OP2(paddl), 3114 }; 3115 3116 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = { 3117 [0 + 2] = MMX_OP2(psrlw), 3118 [0 + 4] = MMX_OP2(psraw), 3119 [0 + 6] = MMX_OP2(psllw), 3120 [8 + 2] = MMX_OP2(psrld), 3121 [8 + 4] = MMX_OP2(psrad), 3122 [8 + 6] = MMX_OP2(pslld), 3123 [16 + 2] = MMX_OP2(psrlq), 3124 [16 + 3] = { NULL, gen_helper_psrldq_xmm }, 3125 [16 + 6] = MMX_OP2(psllq), 3126 [16 + 7] = { NULL, gen_helper_pslldq_xmm }, 3127 }; 3128 3129 static const SSEFunc_0_epi sse_op_table3ai[] = { 3130 gen_helper_cvtsi2ss, 3131 gen_helper_cvtsi2sd 3132 }; 3133 3134 #ifdef TARGET_X86_64 3135 static const SSEFunc_0_epl sse_op_table3aq[] = { 3136 gen_helper_cvtsq2ss, 3137 gen_helper_cvtsq2sd 3138 }; 3139 #endif 3140 3141 static const SSEFunc_i_ep sse_op_table3bi[] = { 3142 gen_helper_cvttss2si, 3143 gen_helper_cvtss2si, 3144 gen_helper_cvttsd2si, 3145 gen_helper_cvtsd2si 3146 }; 3147 3148 #ifdef TARGET_X86_64 3149 static const SSEFunc_l_ep sse_op_table3bq[] = { 3150 gen_helper_cvttss2sq, 3151 gen_helper_cvtss2sq, 3152 gen_helper_cvttsd2sq, 3153 gen_helper_cvtsd2sq 3154 }; 3155 #endif 3156 3157 static const SSEFunc_0_epp sse_op_table4[8][4] = { 3158 SSE_FOP(cmpeq), 3159 SSE_FOP(cmplt), 3160 SSE_FOP(cmple), 3161 SSE_FOP(cmpunord), 3162 SSE_FOP(cmpneq), 3163 SSE_FOP(cmpnlt), 3164 SSE_FOP(cmpnle), 3165 SSE_FOP(cmpord), 3166 }; 3167 3168 static const SSEFunc_0_epp sse_op_table5[256] = { 3169 [0x0c] = gen_helper_pi2fw, 3170 [0x0d] = gen_helper_pi2fd, 3171 [0x1c] = gen_helper_pf2iw, 3172 [0x1d] = gen_helper_pf2id, 3173 [0x8a] = gen_helper_pfnacc, 3174 [0x8e] = gen_helper_pfpnacc, 3175 [0x90] = gen_helper_pfcmpge, 3176 [0x94] = gen_helper_pfmin, 3177 [0x96] = gen_helper_pfrcp, 3178 [0x97] = gen_helper_pfrsqrt, 3179 [0x9a] = gen_helper_pfsub, 3180 [0x9e] = gen_helper_pfadd, 3181 [0xa0] = gen_helper_pfcmpgt, 3182 [0xa4] = gen_helper_pfmax, 3183 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */ 3184 [0xa7] = gen_helper_movq, /* pfrsqit1 */ 3185 [0xaa] = gen_helper_pfsubr, 3186 [0xae] = gen_helper_pfacc, 3187 [0xb0] = gen_helper_pfcmpeq, 3188 [0xb4] = gen_helper_pfmul, 3189 [0xb6] = gen_helper_movq, /* pfrcpit2 */ 3190 [0xb7] = gen_helper_pmulhrw_mmx, 3191 [0xbb] = gen_helper_pswapd, 3192 [0xbf] = gen_helper_pavgb_mmx /* pavgusb */ 3193 }; 3194 3195 struct SSEOpHelper_epp { 3196 SSEFunc_0_epp op[2]; 3197 uint32_t ext_mask; 3198 }; 3199 3200 struct SSEOpHelper_eppi { 3201 SSEFunc_0_eppi op[2]; 3202 uint32_t ext_mask; 3203 }; 3204 3205 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 } 3206 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 } 3207 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 } 3208 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 } 3209 static const struct SSEOpHelper_epp sse_op_table6[256] = { 3210 [0x00] = SSSE3_OP(pshufb), 3211 [0x01] = SSSE3_OP(phaddw), 3212 [0x02] = SSSE3_OP(phaddd), 3213 [0x03] = SSSE3_OP(phaddsw), 3214 [0x04] = SSSE3_OP(pmaddubsw), 3215 [0x05] = SSSE3_OP(phsubw), 3216 [0x06] = SSSE3_OP(phsubd), 3217 [0x07] = SSSE3_OP(phsubsw), 3218 [0x08] = SSSE3_OP(psignb), 3219 [0x09] = SSSE3_OP(psignw), 3220 [0x0a] = SSSE3_OP(psignd), 3221 [0x0b] = SSSE3_OP(pmulhrsw), 3222 [0x10] = SSE41_OP(pblendvb), 3223 [0x14] = SSE41_OP(blendvps), 3224 [0x15] = SSE41_OP(blendvpd), 3225 [0x17] = SSE41_OP(ptest), 3226 [0x1c] = SSSE3_OP(pabsb), 3227 [0x1d] = SSSE3_OP(pabsw), 3228 [0x1e] = SSSE3_OP(pabsd), 3229 [0x20] = SSE41_OP(pmovsxbw), 3230 [0x21] = SSE41_OP(pmovsxbd), 3231 [0x22] = SSE41_OP(pmovsxbq), 3232 [0x23] = SSE41_OP(pmovsxwd), 3233 [0x24] = SSE41_OP(pmovsxwq), 3234 [0x25] = SSE41_OP(pmovsxdq), 3235 [0x28] = SSE41_OP(pmuldq), 3236 [0x29] = SSE41_OP(pcmpeqq), 3237 [0x2a] = SSE41_SPECIAL, /* movntqda */ 3238 [0x2b] = SSE41_OP(packusdw), 3239 [0x30] = SSE41_OP(pmovzxbw), 3240 [0x31] = SSE41_OP(pmovzxbd), 3241 [0x32] = SSE41_OP(pmovzxbq), 3242 [0x33] = SSE41_OP(pmovzxwd), 3243 [0x34] = SSE41_OP(pmovzxwq), 3244 [0x35] = SSE41_OP(pmovzxdq), 3245 [0x37] = SSE42_OP(pcmpgtq), 3246 [0x38] = SSE41_OP(pminsb), 3247 [0x39] = SSE41_OP(pminsd), 3248 [0x3a] = SSE41_OP(pminuw), 3249 [0x3b] = SSE41_OP(pminud), 3250 [0x3c] = SSE41_OP(pmaxsb), 3251 [0x3d] = SSE41_OP(pmaxsd), 3252 [0x3e] = SSE41_OP(pmaxuw), 3253 [0x3f] = SSE41_OP(pmaxud), 3254 [0x40] = SSE41_OP(pmulld), 3255 [0x41] = SSE41_OP(phminposuw), 3256 }; 3257 3258 static const struct SSEOpHelper_eppi sse_op_table7[256] = { 3259 [0x08] = SSE41_OP(roundps), 3260 [0x09] = SSE41_OP(roundpd), 3261 [0x0a] = SSE41_OP(roundss), 3262 [0x0b] = SSE41_OP(roundsd), 3263 [0x0c] = SSE41_OP(blendps), 3264 [0x0d] = SSE41_OP(blendpd), 3265 [0x0e] = SSE41_OP(pblendw), 3266 [0x0f] = SSSE3_OP(palignr), 3267 [0x14] = SSE41_SPECIAL, /* pextrb */ 3268 [0x15] = SSE41_SPECIAL, /* pextrw */ 3269 [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */ 3270 [0x17] = SSE41_SPECIAL, /* extractps */ 3271 [0x20] = SSE41_SPECIAL, /* pinsrb */ 3272 [0x21] = SSE41_SPECIAL, /* insertps */ 3273 [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */ 3274 [0x40] = SSE41_OP(dpps), 3275 [0x41] = SSE41_OP(dppd), 3276 [0x42] = SSE41_OP(mpsadbw), 3277 [0x60] = SSE42_OP(pcmpestrm), 3278 [0x61] = SSE42_OP(pcmpestri), 3279 [0x62] = SSE42_OP(pcmpistrm), 3280 [0x63] = SSE42_OP(pcmpistri), 3281 }; 3282 3283 static void gen_sse(CPUX86State *env, DisasContext *s, int b, 3284 target_ulong pc_start, int rex_r) 3285 { 3286 int b1, op1_offset, op2_offset, is_xmm, val, ot; 3287 int modrm, mod, rm, reg, reg_addr, offset_addr; 3288 SSEFunc_0_epp sse_fn_epp; 3289 SSEFunc_0_eppi sse_fn_eppi; 3290 SSEFunc_0_ppi sse_fn_ppi; 3291 SSEFunc_0_eppt sse_fn_eppt; 3292 3293 b &= 0xff; 3294 if (s->prefix & PREFIX_DATA) 3295 b1 = 1; 3296 else if (s->prefix & PREFIX_REPZ) 3297 b1 = 2; 3298 else if (s->prefix & PREFIX_REPNZ) 3299 b1 = 3; 3300 else 3301 b1 = 0; 3302 sse_fn_epp = sse_op_table1[b][b1]; 3303 if (!sse_fn_epp) { 3304 goto illegal_op; 3305 } 3306 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) { 3307 is_xmm = 1; 3308 } else { 3309 if (b1 == 0) { 3310 /* MMX case */ 3311 is_xmm = 0; 3312 } else { 3313 is_xmm = 1; 3314 } 3315 } 3316 /* simple MMX/SSE operation */ 3317 if (s->flags & HF_TS_MASK) { 3318 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); 3319 return; 3320 } 3321 if (s->flags & HF_EM_MASK) { 3322 illegal_op: 3323 gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base); 3324 return; 3325 } 3326 if (is_xmm && !(s->flags & HF_OSFXSR_MASK)) 3327 if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA)) 3328 goto illegal_op; 3329 if (b == 0x0e) { 3330 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) 3331 goto illegal_op; 3332 /* femms */ 3333 gen_helper_emms(cpu_env); 3334 return; 3335 } 3336 if (b == 0x77) { 3337 /* emms */ 3338 gen_helper_emms(cpu_env); 3339 return; 3340 } 3341 /* prepare MMX state (XXX: optimize by storing fptt and fptags in 3342 the static cpu state) */ 3343 if (!is_xmm) { 3344 gen_helper_enter_mmx(cpu_env); 3345 } 3346 3347 modrm = cpu_ldub_code(env, s->pc++); 3348 reg = ((modrm >> 3) & 7); 3349 if (is_xmm) 3350 reg |= rex_r; 3351 mod = (modrm >> 6) & 3; 3352 if (sse_fn_epp == SSE_SPECIAL) { 3353 b |= (b1 << 8); 3354 switch(b) { 3355 case 0x0e7: /* movntq */ 3356 if (mod == 3) 3357 goto illegal_op; 3358 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3359 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx)); 3360 break; 3361 case 0x1e7: /* movntdq */ 3362 case 0x02b: /* movntps */ 3363 case 0x12b: /* movntps */ 3364 case 0x3f0: /* lddqu */ 3365 if (mod == 3) 3366 goto illegal_op; 3367 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3368 gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); 3369 break; 3370 case 0x6e: /* movd mm, ea */ 3371 #ifdef TARGET_X86_64 3372 if (s->dflag == 2) { 3373 gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 0); 3374 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); 3375 } else 3376 #endif 3377 { 3378 gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 0); 3379 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 3380 offsetof(CPUX86State,fpregs[reg].mmx)); 3381 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 3382 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32); 3383 } 3384 break; 3385 case 0x16e: /* movd xmm, ea */ 3386 #ifdef TARGET_X86_64 3387 if (s->dflag == 2) { 3388 gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 0); 3389 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 3390 offsetof(CPUX86State,xmm_regs[reg])); 3391 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]); 3392 } else 3393 #endif 3394 { 3395 gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 0); 3396 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 3397 offsetof(CPUX86State,xmm_regs[reg])); 3398 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 3399 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32); 3400 } 3401 break; 3402 case 0x6f: /* movq mm, ea */ 3403 if (mod != 3) { 3404 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3405 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx)); 3406 } else { 3407 rm = (modrm & 7); 3408 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, 3409 offsetof(CPUX86State,fpregs[rm].mmx)); 3410 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, 3411 offsetof(CPUX86State,fpregs[reg].mmx)); 3412 } 3413 break; 3414 case 0x010: /* movups */ 3415 case 0x110: /* movupd */ 3416 case 0x028: /* movaps */ 3417 case 0x128: /* movapd */ 3418 case 0x16f: /* movdqa xmm, ea */ 3419 case 0x26f: /* movdqu xmm, ea */ 3420 if (mod != 3) { 3421 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3422 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); 3423 } else { 3424 rm = (modrm & 7) | REX_B(s); 3425 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]), 3426 offsetof(CPUX86State,xmm_regs[rm])); 3427 } 3428 break; 3429 case 0x210: /* movss xmm, ea */ 3430 if (mod != 3) { 3431 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3432 gen_op_ld_T0_A0(OT_LONG + s->mem_index); 3433 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); 3434 gen_op_movl_T0_0(); 3435 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1))); 3436 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2))); 3437 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3))); 3438 } else { 3439 rm = (modrm & 7) | REX_B(s); 3440 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)), 3441 offsetof(CPUX86State,xmm_regs[rm].XMM_L(0))); 3442 } 3443 break; 3444 case 0x310: /* movsd xmm, ea */ 3445 if (mod != 3) { 3446 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3447 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3448 gen_op_movl_T0_0(); 3449 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2))); 3450 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3))); 3451 } else { 3452 rm = (modrm & 7) | REX_B(s); 3453 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)), 3454 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0))); 3455 } 3456 break; 3457 case 0x012: /* movlps */ 3458 case 0x112: /* movlpd */ 3459 if (mod != 3) { 3460 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3461 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3462 } else { 3463 /* movhlps */ 3464 rm = (modrm & 7) | REX_B(s); 3465 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)), 3466 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1))); 3467 } 3468 break; 3469 case 0x212: /* movsldup */ 3470 if (mod != 3) { 3471 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3472 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); 3473 } else { 3474 rm = (modrm & 7) | REX_B(s); 3475 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)), 3476 offsetof(CPUX86State,xmm_regs[rm].XMM_L(0))); 3477 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)), 3478 offsetof(CPUX86State,xmm_regs[rm].XMM_L(2))); 3479 } 3480 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)), 3481 offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); 3482 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)), 3483 offsetof(CPUX86State,xmm_regs[reg].XMM_L(2))); 3484 break; 3485 case 0x312: /* movddup */ 3486 if (mod != 3) { 3487 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3488 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3489 } else { 3490 rm = (modrm & 7) | REX_B(s); 3491 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)), 3492 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0))); 3493 } 3494 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)), 3495 offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3496 break; 3497 case 0x016: /* movhps */ 3498 case 0x116: /* movhpd */ 3499 if (mod != 3) { 3500 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3501 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1))); 3502 } else { 3503 /* movlhps */ 3504 rm = (modrm & 7) | REX_B(s); 3505 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)), 3506 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0))); 3507 } 3508 break; 3509 case 0x216: /* movshdup */ 3510 if (mod != 3) { 3511 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3512 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); 3513 } else { 3514 rm = (modrm & 7) | REX_B(s); 3515 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)), 3516 offsetof(CPUX86State,xmm_regs[rm].XMM_L(1))); 3517 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)), 3518 offsetof(CPUX86State,xmm_regs[rm].XMM_L(3))); 3519 } 3520 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)), 3521 offsetof(CPUX86State,xmm_regs[reg].XMM_L(1))); 3522 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)), 3523 offsetof(CPUX86State,xmm_regs[reg].XMM_L(3))); 3524 break; 3525 case 0x7e: /* movd ea, mm */ 3526 #ifdef TARGET_X86_64 3527 if (s->dflag == 2) { 3528 tcg_gen_ld_i64(cpu_T[0], cpu_env, 3529 offsetof(CPUX86State,fpregs[reg].mmx)); 3530 gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 1); 3531 } else 3532 #endif 3533 { 3534 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 3535 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0))); 3536 gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 1); 3537 } 3538 break; 3539 case 0x17e: /* movd ea, xmm */ 3540 #ifdef TARGET_X86_64 3541 if (s->dflag == 2) { 3542 tcg_gen_ld_i64(cpu_T[0], cpu_env, 3543 offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3544 gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 1); 3545 } else 3546 #endif 3547 { 3548 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 3549 offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); 3550 gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 1); 3551 } 3552 break; 3553 case 0x27e: /* movq xmm, ea */ 3554 if (mod != 3) { 3555 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3556 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3557 } else { 3558 rm = (modrm & 7) | REX_B(s); 3559 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)), 3560 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0))); 3561 } 3562 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1))); 3563 break; 3564 case 0x7f: /* movq ea, mm */ 3565 if (mod != 3) { 3566 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3567 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx)); 3568 } else { 3569 rm = (modrm & 7); 3570 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx), 3571 offsetof(CPUX86State,fpregs[reg].mmx)); 3572 } 3573 break; 3574 case 0x011: /* movups */ 3575 case 0x111: /* movupd */ 3576 case 0x029: /* movaps */ 3577 case 0x129: /* movapd */ 3578 case 0x17f: /* movdqa ea, xmm */ 3579 case 0x27f: /* movdqu ea, xmm */ 3580 if (mod != 3) { 3581 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3582 gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); 3583 } else { 3584 rm = (modrm & 7) | REX_B(s); 3585 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]), 3586 offsetof(CPUX86State,xmm_regs[reg])); 3587 } 3588 break; 3589 case 0x211: /* movss ea, xmm */ 3590 if (mod != 3) { 3591 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3592 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); 3593 gen_op_st_T0_A0(OT_LONG + s->mem_index); 3594 } else { 3595 rm = (modrm & 7) | REX_B(s); 3596 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)), 3597 offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); 3598 } 3599 break; 3600 case 0x311: /* movsd ea, xmm */ 3601 if (mod != 3) { 3602 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3603 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3604 } else { 3605 rm = (modrm & 7) | REX_B(s); 3606 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)), 3607 offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3608 } 3609 break; 3610 case 0x013: /* movlps */ 3611 case 0x113: /* movlpd */ 3612 if (mod != 3) { 3613 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3614 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3615 } else { 3616 goto illegal_op; 3617 } 3618 break; 3619 case 0x017: /* movhps */ 3620 case 0x117: /* movhpd */ 3621 if (mod != 3) { 3622 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3623 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1))); 3624 } else { 3625 goto illegal_op; 3626 } 3627 break; 3628 case 0x71: /* shift mm, im */ 3629 case 0x72: 3630 case 0x73: 3631 case 0x171: /* shift xmm, im */ 3632 case 0x172: 3633 case 0x173: 3634 if (b1 >= 2) { 3635 goto illegal_op; 3636 } 3637 val = cpu_ldub_code(env, s->pc++); 3638 if (is_xmm) { 3639 gen_op_movl_T0_im(val); 3640 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0))); 3641 gen_op_movl_T0_0(); 3642 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1))); 3643 op1_offset = offsetof(CPUX86State,xmm_t0); 3644 } else { 3645 gen_op_movl_T0_im(val); 3646 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0))); 3647 gen_op_movl_T0_0(); 3648 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1))); 3649 op1_offset = offsetof(CPUX86State,mmx_t0); 3650 } 3651 sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 + 3652 (((modrm >> 3)) & 7)][b1]; 3653 if (!sse_fn_epp) { 3654 goto illegal_op; 3655 } 3656 if (is_xmm) { 3657 rm = (modrm & 7) | REX_B(s); 3658 op2_offset = offsetof(CPUX86State,xmm_regs[rm]); 3659 } else { 3660 rm = (modrm & 7); 3661 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 3662 } 3663 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset); 3664 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset); 3665 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); 3666 break; 3667 case 0x050: /* movmskps */ 3668 rm = (modrm & 7) | REX_B(s); 3669 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 3670 offsetof(CPUX86State,xmm_regs[rm])); 3671 gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0); 3672 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 3673 gen_op_mov_reg_T0(OT_LONG, reg); 3674 break; 3675 case 0x150: /* movmskpd */ 3676 rm = (modrm & 7) | REX_B(s); 3677 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 3678 offsetof(CPUX86State,xmm_regs[rm])); 3679 gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0); 3680 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 3681 gen_op_mov_reg_T0(OT_LONG, reg); 3682 break; 3683 case 0x02a: /* cvtpi2ps */ 3684 case 0x12a: /* cvtpi2pd */ 3685 gen_helper_enter_mmx(cpu_env); 3686 if (mod != 3) { 3687 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3688 op2_offset = offsetof(CPUX86State,mmx_t0); 3689 gen_ldq_env_A0(s->mem_index, op2_offset); 3690 } else { 3691 rm = (modrm & 7); 3692 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 3693 } 3694 op1_offset = offsetof(CPUX86State,xmm_regs[reg]); 3695 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 3696 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 3697 switch(b >> 8) { 3698 case 0x0: 3699 gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1); 3700 break; 3701 default: 3702 case 0x1: 3703 gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1); 3704 break; 3705 } 3706 break; 3707 case 0x22a: /* cvtsi2ss */ 3708 case 0x32a: /* cvtsi2sd */ 3709 ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; 3710 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3711 op1_offset = offsetof(CPUX86State,xmm_regs[reg]); 3712 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 3713 if (ot == OT_LONG) { 3714 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1]; 3715 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 3716 sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32); 3717 } else { 3718 #ifdef TARGET_X86_64 3719 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1]; 3720 sse_fn_epl(cpu_env, cpu_ptr0, cpu_T[0]); 3721 #else 3722 goto illegal_op; 3723 #endif 3724 } 3725 break; 3726 case 0x02c: /* cvttps2pi */ 3727 case 0x12c: /* cvttpd2pi */ 3728 case 0x02d: /* cvtps2pi */ 3729 case 0x12d: /* cvtpd2pi */ 3730 gen_helper_enter_mmx(cpu_env); 3731 if (mod != 3) { 3732 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3733 op2_offset = offsetof(CPUX86State,xmm_t0); 3734 gen_ldo_env_A0(s->mem_index, op2_offset); 3735 } else { 3736 rm = (modrm & 7) | REX_B(s); 3737 op2_offset = offsetof(CPUX86State,xmm_regs[rm]); 3738 } 3739 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx); 3740 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 3741 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 3742 switch(b) { 3743 case 0x02c: 3744 gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1); 3745 break; 3746 case 0x12c: 3747 gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1); 3748 break; 3749 case 0x02d: 3750 gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1); 3751 break; 3752 case 0x12d: 3753 gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1); 3754 break; 3755 } 3756 break; 3757 case 0x22c: /* cvttss2si */ 3758 case 0x32c: /* cvttsd2si */ 3759 case 0x22d: /* cvtss2si */ 3760 case 0x32d: /* cvtsd2si */ 3761 ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; 3762 if (mod != 3) { 3763 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3764 if ((b >> 8) & 1) { 3765 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0))); 3766 } else { 3767 gen_op_ld_T0_A0(OT_LONG + s->mem_index); 3768 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0))); 3769 } 3770 op2_offset = offsetof(CPUX86State,xmm_t0); 3771 } else { 3772 rm = (modrm & 7) | REX_B(s); 3773 op2_offset = offsetof(CPUX86State,xmm_regs[rm]); 3774 } 3775 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset); 3776 if (ot == OT_LONG) { 3777 SSEFunc_i_ep sse_fn_i_ep = 3778 sse_op_table3bi[((b >> 7) & 2) | (b & 1)]; 3779 sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0); 3780 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 3781 } else { 3782 #ifdef TARGET_X86_64 3783 SSEFunc_l_ep sse_fn_l_ep = 3784 sse_op_table3bq[((b >> 7) & 2) | (b & 1)]; 3785 sse_fn_l_ep(cpu_T[0], cpu_env, cpu_ptr0); 3786 #else 3787 goto illegal_op; 3788 #endif 3789 } 3790 gen_op_mov_reg_T0(ot, reg); 3791 break; 3792 case 0xc4: /* pinsrw */ 3793 case 0x1c4: 3794 s->rip_offset = 1; 3795 gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); 3796 val = cpu_ldub_code(env, s->pc++); 3797 if (b1) { 3798 val &= 7; 3799 tcg_gen_st16_tl(cpu_T[0], cpu_env, 3800 offsetof(CPUX86State,xmm_regs[reg].XMM_W(val))); 3801 } else { 3802 val &= 3; 3803 tcg_gen_st16_tl(cpu_T[0], cpu_env, 3804 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val))); 3805 } 3806 break; 3807 case 0xc5: /* pextrw */ 3808 case 0x1c5: 3809 if (mod != 3) 3810 goto illegal_op; 3811 ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; 3812 val = cpu_ldub_code(env, s->pc++); 3813 if (b1) { 3814 val &= 7; 3815 rm = (modrm & 7) | REX_B(s); 3816 tcg_gen_ld16u_tl(cpu_T[0], cpu_env, 3817 offsetof(CPUX86State,xmm_regs[rm].XMM_W(val))); 3818 } else { 3819 val &= 3; 3820 rm = (modrm & 7); 3821 tcg_gen_ld16u_tl(cpu_T[0], cpu_env, 3822 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val))); 3823 } 3824 reg = ((modrm >> 3) & 7) | rex_r; 3825 gen_op_mov_reg_T0(ot, reg); 3826 break; 3827 case 0x1d6: /* movq ea, xmm */ 3828 if (mod != 3) { 3829 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3830 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3831 } else { 3832 rm = (modrm & 7) | REX_B(s); 3833 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)), 3834 offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); 3835 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1))); 3836 } 3837 break; 3838 case 0x2d6: /* movq2dq */ 3839 gen_helper_enter_mmx(cpu_env); 3840 rm = (modrm & 7); 3841 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)), 3842 offsetof(CPUX86State,fpregs[rm].mmx)); 3843 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1))); 3844 break; 3845 case 0x3d6: /* movdq2q */ 3846 gen_helper_enter_mmx(cpu_env); 3847 rm = (modrm & 7) | REX_B(s); 3848 gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx), 3849 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0))); 3850 break; 3851 case 0xd7: /* pmovmskb */ 3852 case 0x1d7: 3853 if (mod != 3) 3854 goto illegal_op; 3855 if (b1) { 3856 rm = (modrm & 7) | REX_B(s); 3857 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm])); 3858 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0); 3859 } else { 3860 rm = (modrm & 7); 3861 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx)); 3862 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0); 3863 } 3864 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 3865 reg = ((modrm >> 3) & 7) | rex_r; 3866 gen_op_mov_reg_T0(OT_LONG, reg); 3867 break; 3868 3869 case 0x138: 3870 if (s->prefix & PREFIX_REPNZ) 3871 goto crc32; 3872 case 0x038: 3873 b = modrm; 3874 modrm = cpu_ldub_code(env, s->pc++); 3875 rm = modrm & 7; 3876 reg = ((modrm >> 3) & 7) | rex_r; 3877 mod = (modrm >> 6) & 3; 3878 3879 sse_fn_epp = sse_op_table6[b].op[b1]; 3880 if (!sse_fn_epp) { 3881 goto illegal_op; 3882 } 3883 if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask)) 3884 goto illegal_op; 3885 3886 if (b1) { 3887 op1_offset = offsetof(CPUX86State,xmm_regs[reg]); 3888 if (mod == 3) { 3889 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]); 3890 } else { 3891 op2_offset = offsetof(CPUX86State,xmm_t0); 3892 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3893 switch (b) { 3894 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */ 3895 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */ 3896 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */ 3897 gen_ldq_env_A0(s->mem_index, op2_offset + 3898 offsetof(XMMReg, XMM_Q(0))); 3899 break; 3900 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */ 3901 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */ 3902 tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0, 3903 (s->mem_index >> 2) - 1); 3904 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0); 3905 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset + 3906 offsetof(XMMReg, XMM_L(0))); 3907 break; 3908 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */ 3909 tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0, 3910 (s->mem_index >> 2) - 1); 3911 tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset + 3912 offsetof(XMMReg, XMM_W(0))); 3913 break; 3914 case 0x2a: /* movntqda */ 3915 gen_ldo_env_A0(s->mem_index, op1_offset); 3916 return; 3917 default: 3918 gen_ldo_env_A0(s->mem_index, op2_offset); 3919 } 3920 } 3921 } else { 3922 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); 3923 if (mod == 3) { 3924 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 3925 } else { 3926 op2_offset = offsetof(CPUX86State,mmx_t0); 3927 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3928 gen_ldq_env_A0(s->mem_index, op2_offset); 3929 } 3930 } 3931 if (sse_fn_epp == SSE_SPECIAL) { 3932 goto illegal_op; 3933 } 3934 3935 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 3936 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 3937 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); 3938 3939 if (b == 0x17) { 3940 set_cc_op(s, CC_OP_EFLAGS); 3941 } 3942 break; 3943 case 0x338: /* crc32 */ 3944 crc32: 3945 b = modrm; 3946 modrm = cpu_ldub_code(env, s->pc++); 3947 reg = ((modrm >> 3) & 7) | rex_r; 3948 3949 if (b != 0xf0 && b != 0xf1) 3950 goto illegal_op; 3951 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) 3952 goto illegal_op; 3953 3954 if (b == 0xf0) 3955 ot = OT_BYTE; 3956 else if (b == 0xf1 && s->dflag != 2) 3957 if (s->prefix & PREFIX_DATA) 3958 ot = OT_WORD; 3959 else 3960 ot = OT_LONG; 3961 else 3962 ot = OT_QUAD; 3963 3964 gen_op_mov_TN_reg(OT_LONG, 0, reg); 3965 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 3966 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 3967 gen_helper_crc32(cpu_T[0], cpu_tmp2_i32, 3968 cpu_T[0], tcg_const_i32(8 << ot)); 3969 3970 ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; 3971 gen_op_mov_reg_T0(ot, reg); 3972 break; 3973 3974 case 0x03a: 3975 case 0x13a: 3976 b = modrm; 3977 modrm = cpu_ldub_code(env, s->pc++); 3978 rm = modrm & 7; 3979 reg = ((modrm >> 3) & 7) | rex_r; 3980 mod = (modrm >> 6) & 3; 3981 3982 sse_fn_eppi = sse_op_table7[b].op[b1]; 3983 if (!sse_fn_eppi) { 3984 goto illegal_op; 3985 } 3986 if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask)) 3987 goto illegal_op; 3988 3989 if (sse_fn_eppi == SSE_SPECIAL) { 3990 ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; 3991 rm = (modrm & 7) | REX_B(s); 3992 if (mod != 3) 3993 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 3994 reg = ((modrm >> 3) & 7) | rex_r; 3995 val = cpu_ldub_code(env, s->pc++); 3996 switch (b) { 3997 case 0x14: /* pextrb */ 3998 tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, 3999 xmm_regs[reg].XMM_B(val & 15))); 4000 if (mod == 3) 4001 gen_op_mov_reg_T0(ot, rm); 4002 else 4003 tcg_gen_qemu_st8(cpu_T[0], cpu_A0, 4004 (s->mem_index >> 2) - 1); 4005 break; 4006 case 0x15: /* pextrw */ 4007 tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, 4008 xmm_regs[reg].XMM_W(val & 7))); 4009 if (mod == 3) 4010 gen_op_mov_reg_T0(ot, rm); 4011 else 4012 tcg_gen_qemu_st16(cpu_T[0], cpu_A0, 4013 (s->mem_index >> 2) - 1); 4014 break; 4015 case 0x16: 4016 if (ot == OT_LONG) { /* pextrd */ 4017 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, 4018 offsetof(CPUX86State, 4019 xmm_regs[reg].XMM_L(val & 3))); 4020 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 4021 if (mod == 3) 4022 gen_op_mov_reg_v(ot, rm, cpu_T[0]); 4023 else 4024 tcg_gen_qemu_st32(cpu_T[0], cpu_A0, 4025 (s->mem_index >> 2) - 1); 4026 } else { /* pextrq */ 4027 #ifdef TARGET_X86_64 4028 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, 4029 offsetof(CPUX86State, 4030 xmm_regs[reg].XMM_Q(val & 1))); 4031 if (mod == 3) 4032 gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64); 4033 else 4034 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 4035 (s->mem_index >> 2) - 1); 4036 #else 4037 goto illegal_op; 4038 #endif 4039 } 4040 break; 4041 case 0x17: /* extractps */ 4042 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, 4043 xmm_regs[reg].XMM_L(val & 3))); 4044 if (mod == 3) 4045 gen_op_mov_reg_T0(ot, rm); 4046 else 4047 tcg_gen_qemu_st32(cpu_T[0], cpu_A0, 4048 (s->mem_index >> 2) - 1); 4049 break; 4050 case 0x20: /* pinsrb */ 4051 if (mod == 3) 4052 gen_op_mov_TN_reg(OT_LONG, 0, rm); 4053 else 4054 tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0, 4055 (s->mem_index >> 2) - 1); 4056 tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, 4057 xmm_regs[reg].XMM_B(val & 15))); 4058 break; 4059 case 0x21: /* insertps */ 4060 if (mod == 3) { 4061 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, 4062 offsetof(CPUX86State,xmm_regs[rm] 4063 .XMM_L((val >> 6) & 3))); 4064 } else { 4065 tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0, 4066 (s->mem_index >> 2) - 1); 4067 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0); 4068 } 4069 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, 4070 offsetof(CPUX86State,xmm_regs[reg] 4071 .XMM_L((val >> 4) & 3))); 4072 if ((val >> 0) & 1) 4073 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), 4074 cpu_env, offsetof(CPUX86State, 4075 xmm_regs[reg].XMM_L(0))); 4076 if ((val >> 1) & 1) 4077 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), 4078 cpu_env, offsetof(CPUX86State, 4079 xmm_regs[reg].XMM_L(1))); 4080 if ((val >> 2) & 1) 4081 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), 4082 cpu_env, offsetof(CPUX86State, 4083 xmm_regs[reg].XMM_L(2))); 4084 if ((val >> 3) & 1) 4085 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), 4086 cpu_env, offsetof(CPUX86State, 4087 xmm_regs[reg].XMM_L(3))); 4088 break; 4089 case 0x22: 4090 if (ot == OT_LONG) { /* pinsrd */ 4091 if (mod == 3) 4092 gen_op_mov_v_reg(ot, cpu_tmp0, rm); 4093 else 4094 tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0, 4095 (s->mem_index >> 2) - 1); 4096 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0); 4097 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, 4098 offsetof(CPUX86State, 4099 xmm_regs[reg].XMM_L(val & 3))); 4100 } else { /* pinsrq */ 4101 #ifdef TARGET_X86_64 4102 if (mod == 3) 4103 gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm); 4104 else 4105 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 4106 (s->mem_index >> 2) - 1); 4107 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, 4108 offsetof(CPUX86State, 4109 xmm_regs[reg].XMM_Q(val & 1))); 4110 #else 4111 goto illegal_op; 4112 #endif 4113 } 4114 break; 4115 } 4116 return; 4117 } 4118 4119 if (b1) { 4120 op1_offset = offsetof(CPUX86State,xmm_regs[reg]); 4121 if (mod == 3) { 4122 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]); 4123 } else { 4124 op2_offset = offsetof(CPUX86State,xmm_t0); 4125 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 4126 gen_ldo_env_A0(s->mem_index, op2_offset); 4127 } 4128 } else { 4129 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); 4130 if (mod == 3) { 4131 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 4132 } else { 4133 op2_offset = offsetof(CPUX86State,mmx_t0); 4134 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 4135 gen_ldq_env_A0(s->mem_index, op2_offset); 4136 } 4137 } 4138 val = cpu_ldub_code(env, s->pc++); 4139 4140 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */ 4141 set_cc_op(s, CC_OP_EFLAGS); 4142 4143 if (s->dflag == 2) 4144 /* The helper must use entire 64-bit gp registers */ 4145 val |= 1 << 8; 4146 } 4147 4148 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 4149 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 4150 sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val)); 4151 break; 4152 default: 4153 goto illegal_op; 4154 } 4155 } else { 4156 /* generic MMX or SSE operation */ 4157 switch(b) { 4158 case 0x70: /* pshufx insn */ 4159 case 0xc6: /* pshufx insn */ 4160 case 0xc2: /* compare insns */ 4161 s->rip_offset = 1; 4162 break; 4163 default: 4164 break; 4165 } 4166 if (is_xmm) { 4167 op1_offset = offsetof(CPUX86State,xmm_regs[reg]); 4168 if (mod != 3) { 4169 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 4170 op2_offset = offsetof(CPUX86State,xmm_t0); 4171 if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) || 4172 b == 0xc2)) { 4173 /* specific case for SSE single instructions */ 4174 if (b1 == 2) { 4175 /* 32 bit access */ 4176 gen_op_ld_T0_A0(OT_LONG + s->mem_index); 4177 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0))); 4178 } else { 4179 /* 64 bit access */ 4180 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0))); 4181 } 4182 } else { 4183 gen_ldo_env_A0(s->mem_index, op2_offset); 4184 } 4185 } else { 4186 rm = (modrm & 7) | REX_B(s); 4187 op2_offset = offsetof(CPUX86State,xmm_regs[rm]); 4188 } 4189 } else { 4190 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); 4191 if (mod != 3) { 4192 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 4193 op2_offset = offsetof(CPUX86State,mmx_t0); 4194 gen_ldq_env_A0(s->mem_index, op2_offset); 4195 } else { 4196 rm = (modrm & 7); 4197 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); 4198 } 4199 } 4200 switch(b) { 4201 case 0x0f: /* 3DNow! data insns */ 4202 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) 4203 goto illegal_op; 4204 val = cpu_ldub_code(env, s->pc++); 4205 sse_fn_epp = sse_op_table5[val]; 4206 if (!sse_fn_epp) { 4207 goto illegal_op; 4208 } 4209 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 4210 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 4211 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); 4212 break; 4213 case 0x70: /* pshufx insn */ 4214 case 0xc6: /* pshufx insn */ 4215 val = cpu_ldub_code(env, s->pc++); 4216 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 4217 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 4218 /* XXX: introduce a new table? */ 4219 sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp; 4220 sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val)); 4221 break; 4222 case 0xc2: 4223 /* compare insns */ 4224 val = cpu_ldub_code(env, s->pc++); 4225 if (val >= 8) 4226 goto illegal_op; 4227 sse_fn_epp = sse_op_table4[val][b1]; 4228 4229 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 4230 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 4231 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); 4232 break; 4233 case 0xf7: 4234 /* maskmov : we must prepare A0 */ 4235 if (mod != 3) 4236 goto illegal_op; 4237 #ifdef TARGET_X86_64 4238 if (s->aflag == 2) { 4239 gen_op_movq_A0_reg(R_EDI); 4240 } else 4241 #endif 4242 { 4243 gen_op_movl_A0_reg(R_EDI); 4244 if (s->aflag == 0) 4245 gen_op_andl_A0_ffff(); 4246 } 4247 gen_add_A0_ds_seg(s); 4248 4249 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 4250 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 4251 /* XXX: introduce a new table? */ 4252 sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp; 4253 sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0); 4254 break; 4255 default: 4256 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); 4257 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); 4258 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); 4259 break; 4260 } 4261 if (b == 0x2e || b == 0x2f) { 4262 set_cc_op(s, CC_OP_EFLAGS); 4263 } 4264 } 4265 } 4266 4267 /* convert one instruction. s->is_jmp is set if the translation must 4268 be stopped. Return the next pc value */ 4269 static target_ulong disas_insn(CPUX86State *env, DisasContext *s, target_ulong pc_start) 4270 { 4271 int b, prefixes, aflag, dflag; 4272 int shift, ot; 4273 int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val; 4274 target_ulong next_eip, tval; 4275 #ifdef TARGET_X86_64 4276 int rex_w = -1; 4277 #endif 4278 int rex_r; 4279 4280 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { 4281 tcg_gen_debug_insn_start(pc_start); 4282 } 4283 s->pc = pc_start; 4284 prefixes = 0; 4285 aflag = s->code32; 4286 dflag = s->code32; 4287 s->override = -1; 4288 rex_r = 0; 4289 #ifdef TARGET_X86_64 4290 s->rex_x = 0; 4291 s->rex_b = 0; 4292 x86_64_hregs = 0; 4293 #endif 4294 s->rip_offset = 0; /* for relative ip address */ 4295 next_byte: 4296 b = cpu_ldub_code(env, s->pc); 4297 s->pc++; 4298 /* check prefixes */ 4299 #ifdef TARGET_X86_64 4300 if (CODE64(s)) { 4301 switch (b) { 4302 case 0xf3: 4303 prefixes |= PREFIX_REPZ; 4304 goto next_byte; 4305 case 0xf2: 4306 prefixes |= PREFIX_REPNZ; 4307 goto next_byte; 4308 case 0xf0: 4309 prefixes |= PREFIX_LOCK; 4310 goto next_byte; 4311 case 0x2e: 4312 s->override = R_CS; 4313 goto next_byte; 4314 case 0x36: 4315 s->override = R_SS; 4316 goto next_byte; 4317 case 0x3e: 4318 s->override = R_DS; 4319 goto next_byte; 4320 case 0x26: 4321 s->override = R_ES; 4322 goto next_byte; 4323 case 0x64: 4324 s->override = R_FS; 4325 goto next_byte; 4326 case 0x65: 4327 s->override = R_GS; 4328 goto next_byte; 4329 case 0x66: 4330 prefixes |= PREFIX_DATA; 4331 goto next_byte; 4332 case 0x67: 4333 prefixes |= PREFIX_ADR; 4334 goto next_byte; 4335 case 0x40 ... 0x4f: 4336 /* REX prefix */ 4337 rex_w = (b >> 3) & 1; 4338 rex_r = (b & 0x4) << 1; 4339 s->rex_x = (b & 0x2) << 2; 4340 REX_B(s) = (b & 0x1) << 3; 4341 x86_64_hregs = 1; /* select uniform byte register addressing */ 4342 goto next_byte; 4343 } 4344 if (rex_w == 1) { 4345 /* 0x66 is ignored if rex.w is set */ 4346 dflag = 2; 4347 } else { 4348 if (prefixes & PREFIX_DATA) 4349 dflag ^= 1; 4350 } 4351 if (!(prefixes & PREFIX_ADR)) 4352 aflag = 2; 4353 } else 4354 #endif 4355 { 4356 switch (b) { 4357 case 0xf3: 4358 prefixes |= PREFIX_REPZ; 4359 goto next_byte; 4360 case 0xf2: 4361 prefixes |= PREFIX_REPNZ; 4362 goto next_byte; 4363 case 0xf0: 4364 prefixes |= PREFIX_LOCK; 4365 goto next_byte; 4366 case 0x2e: 4367 s->override = R_CS; 4368 goto next_byte; 4369 case 0x36: 4370 s->override = R_SS; 4371 goto next_byte; 4372 case 0x3e: 4373 s->override = R_DS; 4374 goto next_byte; 4375 case 0x26: 4376 s->override = R_ES; 4377 goto next_byte; 4378 case 0x64: 4379 s->override = R_FS; 4380 goto next_byte; 4381 case 0x65: 4382 s->override = R_GS; 4383 goto next_byte; 4384 case 0x66: 4385 prefixes |= PREFIX_DATA; 4386 goto next_byte; 4387 case 0x67: 4388 prefixes |= PREFIX_ADR; 4389 goto next_byte; 4390 } 4391 if (prefixes & PREFIX_DATA) { 4392 dflag ^= 1; 4393 } 4394 if (prefixes & PREFIX_ADR) { 4395 aflag ^= 1; 4396 } 4397 } 4398 4399 s->prefix = prefixes; 4400 s->aflag = aflag; 4401 s->dflag = dflag; 4402 4403 /* lock generation */ 4404 if (prefixes & PREFIX_LOCK) 4405 gen_helper_lock(); 4406 4407 /* now check op code */ 4408 reswitch: 4409 switch(b) { 4410 case 0x0f: 4411 /**************************/ 4412 /* extended op code */ 4413 b = cpu_ldub_code(env, s->pc++) | 0x100; 4414 goto reswitch; 4415 4416 /**************************/ 4417 /* arith & logic */ 4418 case 0x00 ... 0x05: 4419 case 0x08 ... 0x0d: 4420 case 0x10 ... 0x15: 4421 case 0x18 ... 0x1d: 4422 case 0x20 ... 0x25: 4423 case 0x28 ... 0x2d: 4424 case 0x30 ... 0x35: 4425 case 0x38 ... 0x3d: 4426 { 4427 int op, f, val; 4428 op = (b >> 3) & 7; 4429 f = (b >> 1) & 3; 4430 4431 if ((b & 1) == 0) 4432 ot = OT_BYTE; 4433 else 4434 ot = dflag + OT_WORD; 4435 4436 switch(f) { 4437 case 0: /* OP Ev, Gv */ 4438 modrm = cpu_ldub_code(env, s->pc++); 4439 reg = ((modrm >> 3) & 7) | rex_r; 4440 mod = (modrm >> 6) & 3; 4441 rm = (modrm & 7) | REX_B(s); 4442 if (mod != 3) { 4443 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 4444 opreg = OR_TMP0; 4445 } else if (op == OP_XORL && rm == reg) { 4446 xor_zero: 4447 /* xor reg, reg optimisation */ 4448 gen_op_movl_T0_0(); 4449 set_cc_op(s, CC_OP_LOGICB + ot); 4450 gen_op_mov_reg_T0(ot, reg); 4451 gen_op_update1_cc(); 4452 break; 4453 } else { 4454 opreg = rm; 4455 } 4456 gen_op_mov_TN_reg(ot, 1, reg); 4457 gen_op(s, op, ot, opreg); 4458 break; 4459 case 1: /* OP Gv, Ev */ 4460 modrm = cpu_ldub_code(env, s->pc++); 4461 mod = (modrm >> 6) & 3; 4462 reg = ((modrm >> 3) & 7) | rex_r; 4463 rm = (modrm & 7) | REX_B(s); 4464 if (mod != 3) { 4465 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 4466 gen_op_ld_T1_A0(ot + s->mem_index); 4467 } else if (op == OP_XORL && rm == reg) { 4468 goto xor_zero; 4469 } else { 4470 gen_op_mov_TN_reg(ot, 1, rm); 4471 } 4472 gen_op(s, op, ot, reg); 4473 break; 4474 case 2: /* OP A, Iv */ 4475 val = insn_get(env, s, ot); 4476 gen_op_movl_T1_im(val); 4477 gen_op(s, op, ot, OR_EAX); 4478 break; 4479 } 4480 } 4481 break; 4482 4483 case 0x82: 4484 if (CODE64(s)) 4485 goto illegal_op; 4486 case 0x80: /* GRP1 */ 4487 case 0x81: 4488 case 0x83: 4489 { 4490 int val; 4491 4492 if ((b & 1) == 0) 4493 ot = OT_BYTE; 4494 else 4495 ot = dflag + OT_WORD; 4496 4497 modrm = cpu_ldub_code(env, s->pc++); 4498 mod = (modrm >> 6) & 3; 4499 rm = (modrm & 7) | REX_B(s); 4500 op = (modrm >> 3) & 7; 4501 4502 if (mod != 3) { 4503 if (b == 0x83) 4504 s->rip_offset = 1; 4505 else 4506 s->rip_offset = insn_const_size(ot); 4507 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 4508 opreg = OR_TMP0; 4509 } else { 4510 opreg = rm; 4511 } 4512 4513 switch(b) { 4514 default: 4515 case 0x80: 4516 case 0x81: 4517 case 0x82: 4518 val = insn_get(env, s, ot); 4519 break; 4520 case 0x83: 4521 val = (int8_t)insn_get(env, s, OT_BYTE); 4522 break; 4523 } 4524 gen_op_movl_T1_im(val); 4525 gen_op(s, op, ot, opreg); 4526 } 4527 break; 4528 4529 /**************************/ 4530 /* inc, dec, and other misc arith */ 4531 case 0x40 ... 0x47: /* inc Gv */ 4532 ot = dflag ? OT_LONG : OT_WORD; 4533 gen_inc(s, ot, OR_EAX + (b & 7), 1); 4534 break; 4535 case 0x48 ... 0x4f: /* dec Gv */ 4536 ot = dflag ? OT_LONG : OT_WORD; 4537 gen_inc(s, ot, OR_EAX + (b & 7), -1); 4538 break; 4539 case 0xf6: /* GRP3 */ 4540 case 0xf7: 4541 if ((b & 1) == 0) 4542 ot = OT_BYTE; 4543 else 4544 ot = dflag + OT_WORD; 4545 4546 modrm = cpu_ldub_code(env, s->pc++); 4547 mod = (modrm >> 6) & 3; 4548 rm = (modrm & 7) | REX_B(s); 4549 op = (modrm >> 3) & 7; 4550 if (mod != 3) { 4551 if (op == 0) 4552 s->rip_offset = insn_const_size(ot); 4553 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 4554 gen_op_ld_T0_A0(ot + s->mem_index); 4555 } else { 4556 gen_op_mov_TN_reg(ot, 0, rm); 4557 } 4558 4559 switch(op) { 4560 case 0: /* test */ 4561 val = insn_get(env, s, ot); 4562 gen_op_movl_T1_im(val); 4563 gen_op_testl_T0_T1_cc(); 4564 set_cc_op(s, CC_OP_LOGICB + ot); 4565 break; 4566 case 2: /* not */ 4567 tcg_gen_not_tl(cpu_T[0], cpu_T[0]); 4568 if (mod != 3) { 4569 gen_op_st_T0_A0(ot + s->mem_index); 4570 } else { 4571 gen_op_mov_reg_T0(ot, rm); 4572 } 4573 break; 4574 case 3: /* neg */ 4575 tcg_gen_neg_tl(cpu_T[0], cpu_T[0]); 4576 if (mod != 3) { 4577 gen_op_st_T0_A0(ot + s->mem_index); 4578 } else { 4579 gen_op_mov_reg_T0(ot, rm); 4580 } 4581 gen_op_update_neg_cc(); 4582 set_cc_op(s, CC_OP_SUBB + ot); 4583 break; 4584 case 4: /* mul */ 4585 switch(ot) { 4586 case OT_BYTE: 4587 gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX); 4588 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]); 4589 tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]); 4590 /* XXX: use 32 bit mul which could be faster */ 4591 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 4592 gen_op_mov_reg_T0(OT_WORD, R_EAX); 4593 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4594 tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00); 4595 set_cc_op(s, CC_OP_MULB); 4596 break; 4597 case OT_WORD: 4598 gen_op_mov_TN_reg(OT_WORD, 1, R_EAX); 4599 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]); 4600 tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]); 4601 /* XXX: use 32 bit mul which could be faster */ 4602 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 4603 gen_op_mov_reg_T0(OT_WORD, R_EAX); 4604 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4605 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16); 4606 gen_op_mov_reg_T0(OT_WORD, R_EDX); 4607 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]); 4608 set_cc_op(s, CC_OP_MULW); 4609 break; 4610 default: 4611 case OT_LONG: 4612 #ifdef TARGET_X86_64 4613 gen_op_mov_TN_reg(OT_LONG, 1, R_EAX); 4614 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); 4615 tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); 4616 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 4617 gen_op_mov_reg_T0(OT_LONG, R_EAX); 4618 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4619 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32); 4620 gen_op_mov_reg_T0(OT_LONG, R_EDX); 4621 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]); 4622 #else 4623 { 4624 TCGv_i64 t0, t1; 4625 t0 = tcg_temp_new_i64(); 4626 t1 = tcg_temp_new_i64(); 4627 gen_op_mov_TN_reg(OT_LONG, 1, R_EAX); 4628 tcg_gen_extu_i32_i64(t0, cpu_T[0]); 4629 tcg_gen_extu_i32_i64(t1, cpu_T[1]); 4630 tcg_gen_mul_i64(t0, t0, t1); 4631 tcg_gen_trunc_i64_i32(cpu_T[0], t0); 4632 gen_op_mov_reg_T0(OT_LONG, R_EAX); 4633 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4634 tcg_gen_shri_i64(t0, t0, 32); 4635 tcg_gen_trunc_i64_i32(cpu_T[0], t0); 4636 gen_op_mov_reg_T0(OT_LONG, R_EDX); 4637 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]); 4638 } 4639 #endif 4640 set_cc_op(s, CC_OP_MULL); 4641 break; 4642 #ifdef TARGET_X86_64 4643 case OT_QUAD: 4644 gen_helper_mulq_EAX_T0(cpu_env, cpu_T[0]); 4645 set_cc_op(s, CC_OP_MULQ); 4646 break; 4647 #endif 4648 } 4649 break; 4650 case 5: /* imul */ 4651 switch(ot) { 4652 case OT_BYTE: 4653 gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX); 4654 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]); 4655 tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]); 4656 /* XXX: use 32 bit mul which could be faster */ 4657 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 4658 gen_op_mov_reg_T0(OT_WORD, R_EAX); 4659 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4660 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]); 4661 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0); 4662 set_cc_op(s, CC_OP_MULB); 4663 break; 4664 case OT_WORD: 4665 gen_op_mov_TN_reg(OT_WORD, 1, R_EAX); 4666 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); 4667 tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]); 4668 /* XXX: use 32 bit mul which could be faster */ 4669 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 4670 gen_op_mov_reg_T0(OT_WORD, R_EAX); 4671 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4672 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]); 4673 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0); 4674 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16); 4675 gen_op_mov_reg_T0(OT_WORD, R_EDX); 4676 set_cc_op(s, CC_OP_MULW); 4677 break; 4678 default: 4679 case OT_LONG: 4680 #ifdef TARGET_X86_64 4681 gen_op_mov_TN_reg(OT_LONG, 1, R_EAX); 4682 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); 4683 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); 4684 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 4685 gen_op_mov_reg_T0(OT_LONG, R_EAX); 4686 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4687 tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]); 4688 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0); 4689 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32); 4690 gen_op_mov_reg_T0(OT_LONG, R_EDX); 4691 #else 4692 { 4693 TCGv_i64 t0, t1; 4694 t0 = tcg_temp_new_i64(); 4695 t1 = tcg_temp_new_i64(); 4696 gen_op_mov_TN_reg(OT_LONG, 1, R_EAX); 4697 tcg_gen_ext_i32_i64(t0, cpu_T[0]); 4698 tcg_gen_ext_i32_i64(t1, cpu_T[1]); 4699 tcg_gen_mul_i64(t0, t0, t1); 4700 tcg_gen_trunc_i64_i32(cpu_T[0], t0); 4701 gen_op_mov_reg_T0(OT_LONG, R_EAX); 4702 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4703 tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31); 4704 tcg_gen_shri_i64(t0, t0, 32); 4705 tcg_gen_trunc_i64_i32(cpu_T[0], t0); 4706 gen_op_mov_reg_T0(OT_LONG, R_EDX); 4707 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0); 4708 } 4709 #endif 4710 set_cc_op(s, CC_OP_MULL); 4711 break; 4712 #ifdef TARGET_X86_64 4713 case OT_QUAD: 4714 gen_helper_imulq_EAX_T0(cpu_env, cpu_T[0]); 4715 set_cc_op(s, CC_OP_MULQ); 4716 break; 4717 #endif 4718 } 4719 break; 4720 case 6: /* div */ 4721 switch(ot) { 4722 case OT_BYTE: 4723 gen_jmp_im(pc_start - s->cs_base); 4724 gen_helper_divb_AL(cpu_env, cpu_T[0]); 4725 break; 4726 case OT_WORD: 4727 gen_jmp_im(pc_start - s->cs_base); 4728 gen_helper_divw_AX(cpu_env, cpu_T[0]); 4729 break; 4730 default: 4731 case OT_LONG: 4732 gen_jmp_im(pc_start - s->cs_base); 4733 gen_helper_divl_EAX(cpu_env, cpu_T[0]); 4734 break; 4735 #ifdef TARGET_X86_64 4736 case OT_QUAD: 4737 gen_jmp_im(pc_start - s->cs_base); 4738 gen_helper_divq_EAX(cpu_env, cpu_T[0]); 4739 break; 4740 #endif 4741 } 4742 break; 4743 case 7: /* idiv */ 4744 switch(ot) { 4745 case OT_BYTE: 4746 gen_jmp_im(pc_start - s->cs_base); 4747 gen_helper_idivb_AL(cpu_env, cpu_T[0]); 4748 break; 4749 case OT_WORD: 4750 gen_jmp_im(pc_start - s->cs_base); 4751 gen_helper_idivw_AX(cpu_env, cpu_T[0]); 4752 break; 4753 default: 4754 case OT_LONG: 4755 gen_jmp_im(pc_start - s->cs_base); 4756 gen_helper_idivl_EAX(cpu_env, cpu_T[0]); 4757 break; 4758 #ifdef TARGET_X86_64 4759 case OT_QUAD: 4760 gen_jmp_im(pc_start - s->cs_base); 4761 gen_helper_idivq_EAX(cpu_env, cpu_T[0]); 4762 break; 4763 #endif 4764 } 4765 break; 4766 default: 4767 goto illegal_op; 4768 } 4769 break; 4770 4771 case 0xfe: /* GRP4 */ 4772 case 0xff: /* GRP5 */ 4773 if ((b & 1) == 0) 4774 ot = OT_BYTE; 4775 else 4776 ot = dflag + OT_WORD; 4777 4778 modrm = cpu_ldub_code(env, s->pc++); 4779 mod = (modrm >> 6) & 3; 4780 rm = (modrm & 7) | REX_B(s); 4781 op = (modrm >> 3) & 7; 4782 if (op >= 2 && b == 0xfe) { 4783 goto illegal_op; 4784 } 4785 if (CODE64(s)) { 4786 if (op == 2 || op == 4) { 4787 /* operand size for jumps is 64 bit */ 4788 ot = OT_QUAD; 4789 } else if (op == 3 || op == 5) { 4790 /* for call calls, the operand is 16 or 32 bit, even 4791 in long mode */ 4792 ot = dflag ? OT_LONG : OT_WORD; 4793 } else if (op == 6) { 4794 /* default push size is 64 bit */ 4795 ot = dflag ? OT_QUAD : OT_WORD; 4796 } 4797 } 4798 if (mod != 3) { 4799 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 4800 if (op >= 2 && op != 3 && op != 5) 4801 gen_op_ld_T0_A0(ot + s->mem_index); 4802 } else { 4803 gen_op_mov_TN_reg(ot, 0, rm); 4804 } 4805 4806 switch(op) { 4807 case 0: /* inc Ev */ 4808 if (mod != 3) 4809 opreg = OR_TMP0; 4810 else 4811 opreg = rm; 4812 gen_inc(s, ot, opreg, 1); 4813 break; 4814 case 1: /* dec Ev */ 4815 if (mod != 3) 4816 opreg = OR_TMP0; 4817 else 4818 opreg = rm; 4819 gen_inc(s, ot, opreg, -1); 4820 break; 4821 case 2: /* call Ev */ 4822 /* XXX: optimize if memory (no 'and' is necessary) */ 4823 if (s->dflag == 0) 4824 gen_op_andl_T0_ffff(); 4825 next_eip = s->pc - s->cs_base; 4826 gen_movtl_T1_im(next_eip); 4827 gen_push_T1(s); 4828 gen_op_jmp_T0(); 4829 gen_eob(s); 4830 break; 4831 case 3: /* lcall Ev */ 4832 gen_op_ld_T1_A0(ot + s->mem_index); 4833 gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); 4834 gen_op_ldu_T0_A0(OT_WORD + s->mem_index); 4835 do_lcall: 4836 if (s->pe && !s->vm86) { 4837 gen_update_cc_op(s); 4838 gen_jmp_im(pc_start - s->cs_base); 4839 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 4840 gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T[1], 4841 tcg_const_i32(dflag), 4842 tcg_const_i32(s->pc - pc_start)); 4843 } else { 4844 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 4845 gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T[1], 4846 tcg_const_i32(dflag), 4847 tcg_const_i32(s->pc - s->cs_base)); 4848 } 4849 gen_eob(s); 4850 break; 4851 case 4: /* jmp Ev */ 4852 if (s->dflag == 0) 4853 gen_op_andl_T0_ffff(); 4854 gen_op_jmp_T0(); 4855 gen_eob(s); 4856 break; 4857 case 5: /* ljmp Ev */ 4858 gen_op_ld_T1_A0(ot + s->mem_index); 4859 gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); 4860 gen_op_ldu_T0_A0(OT_WORD + s->mem_index); 4861 do_ljmp: 4862 if (s->pe && !s->vm86) { 4863 gen_update_cc_op(s); 4864 gen_jmp_im(pc_start - s->cs_base); 4865 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 4866 gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T[1], 4867 tcg_const_i32(s->pc - pc_start)); 4868 } else { 4869 gen_op_movl_seg_T0_vm(R_CS); 4870 gen_op_movl_T0_T1(); 4871 gen_op_jmp_T0(); 4872 } 4873 gen_eob(s); 4874 break; 4875 case 6: /* push Ev */ 4876 gen_push_T0(s); 4877 break; 4878 default: 4879 goto illegal_op; 4880 } 4881 break; 4882 4883 case 0x84: /* test Ev, Gv */ 4884 case 0x85: 4885 if ((b & 1) == 0) 4886 ot = OT_BYTE; 4887 else 4888 ot = dflag + OT_WORD; 4889 4890 modrm = cpu_ldub_code(env, s->pc++); 4891 mod = (modrm >> 6) & 3; 4892 rm = (modrm & 7) | REX_B(s); 4893 reg = ((modrm >> 3) & 7) | rex_r; 4894 4895 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 4896 gen_op_mov_TN_reg(ot, 1, reg); 4897 gen_op_testl_T0_T1_cc(); 4898 set_cc_op(s, CC_OP_LOGICB + ot); 4899 break; 4900 4901 case 0xa8: /* test eAX, Iv */ 4902 case 0xa9: 4903 if ((b & 1) == 0) 4904 ot = OT_BYTE; 4905 else 4906 ot = dflag + OT_WORD; 4907 val = insn_get(env, s, ot); 4908 4909 gen_op_mov_TN_reg(ot, 0, OR_EAX); 4910 gen_op_movl_T1_im(val); 4911 gen_op_testl_T0_T1_cc(); 4912 set_cc_op(s, CC_OP_LOGICB + ot); 4913 break; 4914 4915 case 0x98: /* CWDE/CBW */ 4916 #ifdef TARGET_X86_64 4917 if (dflag == 2) { 4918 gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); 4919 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); 4920 gen_op_mov_reg_T0(OT_QUAD, R_EAX); 4921 } else 4922 #endif 4923 if (dflag == 1) { 4924 gen_op_mov_TN_reg(OT_WORD, 0, R_EAX); 4925 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); 4926 gen_op_mov_reg_T0(OT_LONG, R_EAX); 4927 } else { 4928 gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX); 4929 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]); 4930 gen_op_mov_reg_T0(OT_WORD, R_EAX); 4931 } 4932 break; 4933 case 0x99: /* CDQ/CWD */ 4934 #ifdef TARGET_X86_64 4935 if (dflag == 2) { 4936 gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX); 4937 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63); 4938 gen_op_mov_reg_T0(OT_QUAD, R_EDX); 4939 } else 4940 #endif 4941 if (dflag == 1) { 4942 gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); 4943 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); 4944 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31); 4945 gen_op_mov_reg_T0(OT_LONG, R_EDX); 4946 } else { 4947 gen_op_mov_TN_reg(OT_WORD, 0, R_EAX); 4948 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); 4949 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15); 4950 gen_op_mov_reg_T0(OT_WORD, R_EDX); 4951 } 4952 break; 4953 case 0x1af: /* imul Gv, Ev */ 4954 case 0x69: /* imul Gv, Ev, I */ 4955 case 0x6b: 4956 ot = dflag + OT_WORD; 4957 modrm = cpu_ldub_code(env, s->pc++); 4958 reg = ((modrm >> 3) & 7) | rex_r; 4959 if (b == 0x69) 4960 s->rip_offset = insn_const_size(ot); 4961 else if (b == 0x6b) 4962 s->rip_offset = 1; 4963 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 4964 if (b == 0x69) { 4965 val = insn_get(env, s, ot); 4966 gen_op_movl_T1_im(val); 4967 } else if (b == 0x6b) { 4968 val = (int8_t)insn_get(env, s, OT_BYTE); 4969 gen_op_movl_T1_im(val); 4970 } else { 4971 gen_op_mov_TN_reg(ot, 1, reg); 4972 } 4973 4974 #ifdef TARGET_X86_64 4975 if (ot == OT_QUAD) { 4976 gen_helper_imulq_T0_T1(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); 4977 } else 4978 #endif 4979 if (ot == OT_LONG) { 4980 #ifdef TARGET_X86_64 4981 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); 4982 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); 4983 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 4984 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4985 tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]); 4986 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0); 4987 #else 4988 { 4989 TCGv_i64 t0, t1; 4990 t0 = tcg_temp_new_i64(); 4991 t1 = tcg_temp_new_i64(); 4992 tcg_gen_ext_i32_i64(t0, cpu_T[0]); 4993 tcg_gen_ext_i32_i64(t1, cpu_T[1]); 4994 tcg_gen_mul_i64(t0, t0, t1); 4995 tcg_gen_trunc_i64_i32(cpu_T[0], t0); 4996 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 4997 tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31); 4998 tcg_gen_shri_i64(t0, t0, 32); 4999 tcg_gen_trunc_i64_i32(cpu_T[1], t0); 5000 tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0); 5001 } 5002 #endif 5003 } else { 5004 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); 5005 tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]); 5006 /* XXX: use 32 bit mul which could be faster */ 5007 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 5008 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); 5009 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]); 5010 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0); 5011 } 5012 gen_op_mov_reg_T0(ot, reg); 5013 set_cc_op(s, CC_OP_MULB + ot); 5014 break; 5015 case 0x1c0: 5016 case 0x1c1: /* xadd Ev, Gv */ 5017 if ((b & 1) == 0) 5018 ot = OT_BYTE; 5019 else 5020 ot = dflag + OT_WORD; 5021 modrm = cpu_ldub_code(env, s->pc++); 5022 reg = ((modrm >> 3) & 7) | rex_r; 5023 mod = (modrm >> 6) & 3; 5024 if (mod == 3) { 5025 rm = (modrm & 7) | REX_B(s); 5026 gen_op_mov_TN_reg(ot, 0, reg); 5027 gen_op_mov_TN_reg(ot, 1, rm); 5028 gen_op_addl_T0_T1(); 5029 gen_op_mov_reg_T1(ot, reg); 5030 gen_op_mov_reg_T0(ot, rm); 5031 } else { 5032 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5033 gen_op_mov_TN_reg(ot, 0, reg); 5034 gen_op_ld_T1_A0(ot + s->mem_index); 5035 gen_op_addl_T0_T1(); 5036 gen_op_st_T0_A0(ot + s->mem_index); 5037 gen_op_mov_reg_T1(ot, reg); 5038 } 5039 gen_op_update2_cc(); 5040 set_cc_op(s, CC_OP_ADDB + ot); 5041 break; 5042 case 0x1b0: 5043 case 0x1b1: /* cmpxchg Ev, Gv */ 5044 { 5045 int label1, label2; 5046 TCGv t0, t1, t2, a0; 5047 5048 if ((b & 1) == 0) 5049 ot = OT_BYTE; 5050 else 5051 ot = dflag + OT_WORD; 5052 modrm = cpu_ldub_code(env, s->pc++); 5053 reg = ((modrm >> 3) & 7) | rex_r; 5054 mod = (modrm >> 6) & 3; 5055 t0 = tcg_temp_local_new(); 5056 t1 = tcg_temp_local_new(); 5057 t2 = tcg_temp_local_new(); 5058 a0 = tcg_temp_local_new(); 5059 gen_op_mov_v_reg(ot, t1, reg); 5060 if (mod == 3) { 5061 rm = (modrm & 7) | REX_B(s); 5062 gen_op_mov_v_reg(ot, t0, rm); 5063 } else { 5064 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5065 tcg_gen_mov_tl(a0, cpu_A0); 5066 gen_op_ld_v(ot + s->mem_index, t0, a0); 5067 rm = 0; /* avoid warning */ 5068 } 5069 label1 = gen_new_label(); 5070 tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUX86State, regs[R_EAX])); 5071 tcg_gen_sub_tl(t2, t2, t0); 5072 gen_extu(ot, t2); 5073 tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1); 5074 if (mod == 3) { 5075 label2 = gen_new_label(); 5076 gen_op_mov_reg_v(ot, R_EAX, t0); 5077 tcg_gen_br(label2); 5078 gen_set_label(label1); 5079 gen_op_mov_reg_v(ot, rm, t1); 5080 gen_set_label(label2); 5081 } else { 5082 tcg_gen_mov_tl(t1, t0); 5083 gen_op_mov_reg_v(ot, R_EAX, t0); 5084 gen_set_label(label1); 5085 /* always store */ 5086 gen_op_st_v(ot + s->mem_index, t1, a0); 5087 } 5088 tcg_gen_mov_tl(cpu_cc_src, t0); 5089 tcg_gen_mov_tl(cpu_cc_dst, t2); 5090 set_cc_op(s, CC_OP_SUBB + ot); 5091 tcg_temp_free(t0); 5092 tcg_temp_free(t1); 5093 tcg_temp_free(t2); 5094 tcg_temp_free(a0); 5095 } 5096 break; 5097 case 0x1c7: /* cmpxchg8b */ 5098 modrm = cpu_ldub_code(env, s->pc++); 5099 mod = (modrm >> 6) & 3; 5100 if ((mod == 3) || ((modrm & 0x38) != 0x8)) 5101 goto illegal_op; 5102 #ifdef TARGET_X86_64 5103 if (dflag == 2) { 5104 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) 5105 goto illegal_op; 5106 gen_jmp_im(pc_start - s->cs_base); 5107 gen_update_cc_op(s); 5108 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5109 gen_helper_cmpxchg16b(cpu_env, cpu_A0); 5110 } else 5111 #endif 5112 { 5113 if (!(s->cpuid_features & CPUID_CX8)) 5114 goto illegal_op; 5115 gen_jmp_im(pc_start - s->cs_base); 5116 gen_update_cc_op(s); 5117 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5118 gen_helper_cmpxchg8b(cpu_env, cpu_A0); 5119 } 5120 set_cc_op(s, CC_OP_EFLAGS); 5121 break; 5122 5123 /**************************/ 5124 /* push/pop */ 5125 case 0x50 ... 0x57: /* push */ 5126 gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s)); 5127 gen_push_T0(s); 5128 break; 5129 case 0x58 ... 0x5f: /* pop */ 5130 if (CODE64(s)) { 5131 ot = dflag ? OT_QUAD : OT_WORD; 5132 } else { 5133 ot = dflag + OT_WORD; 5134 } 5135 gen_pop_T0(s); 5136 /* NOTE: order is important for pop %sp */ 5137 gen_pop_update(s); 5138 gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s)); 5139 break; 5140 case 0x60: /* pusha */ 5141 if (CODE64(s)) 5142 goto illegal_op; 5143 gen_pusha(s); 5144 break; 5145 case 0x61: /* popa */ 5146 if (CODE64(s)) 5147 goto illegal_op; 5148 gen_popa(s); 5149 break; 5150 case 0x68: /* push Iv */ 5151 case 0x6a: 5152 if (CODE64(s)) { 5153 ot = dflag ? OT_QUAD : OT_WORD; 5154 } else { 5155 ot = dflag + OT_WORD; 5156 } 5157 if (b == 0x68) 5158 val = insn_get(env, s, ot); 5159 else 5160 val = (int8_t)insn_get(env, s, OT_BYTE); 5161 gen_op_movl_T0_im(val); 5162 gen_push_T0(s); 5163 break; 5164 case 0x8f: /* pop Ev */ 5165 if (CODE64(s)) { 5166 ot = dflag ? OT_QUAD : OT_WORD; 5167 } else { 5168 ot = dflag + OT_WORD; 5169 } 5170 modrm = cpu_ldub_code(env, s->pc++); 5171 mod = (modrm >> 6) & 3; 5172 gen_pop_T0(s); 5173 if (mod == 3) { 5174 /* NOTE: order is important for pop %sp */ 5175 gen_pop_update(s); 5176 rm = (modrm & 7) | REX_B(s); 5177 gen_op_mov_reg_T0(ot, rm); 5178 } else { 5179 /* NOTE: order is important too for MMU exceptions */ 5180 s->popl_esp_hack = 1 << ot; 5181 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 5182 s->popl_esp_hack = 0; 5183 gen_pop_update(s); 5184 } 5185 break; 5186 case 0xc8: /* enter */ 5187 { 5188 int level; 5189 val = cpu_lduw_code(env, s->pc); 5190 s->pc += 2; 5191 level = cpu_ldub_code(env, s->pc++); 5192 gen_enter(s, val, level); 5193 } 5194 break; 5195 case 0xc9: /* leave */ 5196 /* XXX: exception not precise (ESP is updated before potential exception) */ 5197 if (CODE64(s)) { 5198 gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP); 5199 gen_op_mov_reg_T0(OT_QUAD, R_ESP); 5200 } else if (s->ss32) { 5201 gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); 5202 gen_op_mov_reg_T0(OT_LONG, R_ESP); 5203 } else { 5204 gen_op_mov_TN_reg(OT_WORD, 0, R_EBP); 5205 gen_op_mov_reg_T0(OT_WORD, R_ESP); 5206 } 5207 gen_pop_T0(s); 5208 if (CODE64(s)) { 5209 ot = dflag ? OT_QUAD : OT_WORD; 5210 } else { 5211 ot = dflag + OT_WORD; 5212 } 5213 gen_op_mov_reg_T0(ot, R_EBP); 5214 gen_pop_update(s); 5215 break; 5216 case 0x06: /* push es */ 5217 case 0x0e: /* push cs */ 5218 case 0x16: /* push ss */ 5219 case 0x1e: /* push ds */ 5220 if (CODE64(s)) 5221 goto illegal_op; 5222 gen_op_movl_T0_seg(b >> 3); 5223 gen_push_T0(s); 5224 break; 5225 case 0x1a0: /* push fs */ 5226 case 0x1a8: /* push gs */ 5227 gen_op_movl_T0_seg((b >> 3) & 7); 5228 gen_push_T0(s); 5229 break; 5230 case 0x07: /* pop es */ 5231 case 0x17: /* pop ss */ 5232 case 0x1f: /* pop ds */ 5233 if (CODE64(s)) 5234 goto illegal_op; 5235 reg = b >> 3; 5236 gen_pop_T0(s); 5237 gen_movl_seg_T0(s, reg, pc_start - s->cs_base); 5238 gen_pop_update(s); 5239 if (reg == R_SS) { 5240 /* if reg == SS, inhibit interrupts/trace. */ 5241 /* If several instructions disable interrupts, only the 5242 _first_ does it */ 5243 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK)) 5244 gen_helper_set_inhibit_irq(cpu_env); 5245 s->tf = 0; 5246 } 5247 if (s->is_jmp) { 5248 gen_jmp_im(s->pc - s->cs_base); 5249 gen_eob(s); 5250 } 5251 break; 5252 case 0x1a1: /* pop fs */ 5253 case 0x1a9: /* pop gs */ 5254 gen_pop_T0(s); 5255 gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base); 5256 gen_pop_update(s); 5257 if (s->is_jmp) { 5258 gen_jmp_im(s->pc - s->cs_base); 5259 gen_eob(s); 5260 } 5261 break; 5262 5263 /**************************/ 5264 /* mov */ 5265 case 0x88: 5266 case 0x89: /* mov Gv, Ev */ 5267 if ((b & 1) == 0) 5268 ot = OT_BYTE; 5269 else 5270 ot = dflag + OT_WORD; 5271 modrm = cpu_ldub_code(env, s->pc++); 5272 reg = ((modrm >> 3) & 7) | rex_r; 5273 5274 /* generate a generic store */ 5275 gen_ldst_modrm(env, s, modrm, ot, reg, 1); 5276 break; 5277 case 0xc6: 5278 case 0xc7: /* mov Ev, Iv */ 5279 if ((b & 1) == 0) 5280 ot = OT_BYTE; 5281 else 5282 ot = dflag + OT_WORD; 5283 modrm = cpu_ldub_code(env, s->pc++); 5284 mod = (modrm >> 6) & 3; 5285 if (mod != 3) { 5286 s->rip_offset = insn_const_size(ot); 5287 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5288 } 5289 val = insn_get(env, s, ot); 5290 gen_op_movl_T0_im(val); 5291 if (mod != 3) 5292 gen_op_st_T0_A0(ot + s->mem_index); 5293 else 5294 gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s)); 5295 break; 5296 case 0x8a: 5297 case 0x8b: /* mov Ev, Gv */ 5298 if ((b & 1) == 0) 5299 ot = OT_BYTE; 5300 else 5301 ot = OT_WORD + dflag; 5302 modrm = cpu_ldub_code(env, s->pc++); 5303 reg = ((modrm >> 3) & 7) | rex_r; 5304 5305 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 5306 gen_op_mov_reg_T0(ot, reg); 5307 break; 5308 case 0x8e: /* mov seg, Gv */ 5309 modrm = cpu_ldub_code(env, s->pc++); 5310 reg = (modrm >> 3) & 7; 5311 if (reg >= 6 || reg == R_CS) 5312 goto illegal_op; 5313 gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); 5314 gen_movl_seg_T0(s, reg, pc_start - s->cs_base); 5315 if (reg == R_SS) { 5316 /* if reg == SS, inhibit interrupts/trace */ 5317 /* If several instructions disable interrupts, only the 5318 _first_ does it */ 5319 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK)) 5320 gen_helper_set_inhibit_irq(cpu_env); 5321 s->tf = 0; 5322 } 5323 if (s->is_jmp) { 5324 gen_jmp_im(s->pc - s->cs_base); 5325 gen_eob(s); 5326 } 5327 break; 5328 case 0x8c: /* mov Gv, seg */ 5329 modrm = cpu_ldub_code(env, s->pc++); 5330 reg = (modrm >> 3) & 7; 5331 mod = (modrm >> 6) & 3; 5332 if (reg >= 6) 5333 goto illegal_op; 5334 gen_op_movl_T0_seg(reg); 5335 if (mod == 3) 5336 ot = OT_WORD + dflag; 5337 else 5338 ot = OT_WORD; 5339 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 5340 break; 5341 5342 case 0x1b6: /* movzbS Gv, Eb */ 5343 case 0x1b7: /* movzwS Gv, Eb */ 5344 case 0x1be: /* movsbS Gv, Eb */ 5345 case 0x1bf: /* movswS Gv, Eb */ 5346 { 5347 int d_ot; 5348 /* d_ot is the size of destination */ 5349 d_ot = dflag + OT_WORD; 5350 /* ot is the size of source */ 5351 ot = (b & 1) + OT_BYTE; 5352 modrm = cpu_ldub_code(env, s->pc++); 5353 reg = ((modrm >> 3) & 7) | rex_r; 5354 mod = (modrm >> 6) & 3; 5355 rm = (modrm & 7) | REX_B(s); 5356 5357 if (mod == 3) { 5358 gen_op_mov_TN_reg(ot, 0, rm); 5359 switch(ot | (b & 8)) { 5360 case OT_BYTE: 5361 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]); 5362 break; 5363 case OT_BYTE | 8: 5364 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]); 5365 break; 5366 case OT_WORD: 5367 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]); 5368 break; 5369 default: 5370 case OT_WORD | 8: 5371 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); 5372 break; 5373 } 5374 gen_op_mov_reg_T0(d_ot, reg); 5375 } else { 5376 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5377 if (b & 8) { 5378 gen_op_lds_T0_A0(ot + s->mem_index); 5379 } else { 5380 gen_op_ldu_T0_A0(ot + s->mem_index); 5381 } 5382 gen_op_mov_reg_T0(d_ot, reg); 5383 } 5384 } 5385 break; 5386 5387 case 0x8d: /* lea */ 5388 ot = dflag + OT_WORD; 5389 modrm = cpu_ldub_code(env, s->pc++); 5390 mod = (modrm >> 6) & 3; 5391 if (mod == 3) 5392 goto illegal_op; 5393 reg = ((modrm >> 3) & 7) | rex_r; 5394 /* we must ensure that no segment is added */ 5395 s->override = -1; 5396 val = s->addseg; 5397 s->addseg = 0; 5398 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5399 s->addseg = val; 5400 gen_op_mov_reg_A0(ot - OT_WORD, reg); 5401 break; 5402 5403 case 0xa0: /* mov EAX, Ov */ 5404 case 0xa1: 5405 case 0xa2: /* mov Ov, EAX */ 5406 case 0xa3: 5407 { 5408 target_ulong offset_addr; 5409 5410 if ((b & 1) == 0) 5411 ot = OT_BYTE; 5412 else 5413 ot = dflag + OT_WORD; 5414 #ifdef TARGET_X86_64 5415 if (s->aflag == 2) { 5416 offset_addr = cpu_ldq_code(env, s->pc); 5417 s->pc += 8; 5418 gen_op_movq_A0_im(offset_addr); 5419 } else 5420 #endif 5421 { 5422 if (s->aflag) { 5423 offset_addr = insn_get(env, s, OT_LONG); 5424 } else { 5425 offset_addr = insn_get(env, s, OT_WORD); 5426 } 5427 gen_op_movl_A0_im(offset_addr); 5428 } 5429 gen_add_A0_ds_seg(s); 5430 if ((b & 2) == 0) { 5431 gen_op_ld_T0_A0(ot + s->mem_index); 5432 gen_op_mov_reg_T0(ot, R_EAX); 5433 } else { 5434 gen_op_mov_TN_reg(ot, 0, R_EAX); 5435 gen_op_st_T0_A0(ot + s->mem_index); 5436 } 5437 } 5438 break; 5439 case 0xd7: /* xlat */ 5440 #ifdef TARGET_X86_64 5441 if (s->aflag == 2) { 5442 gen_op_movq_A0_reg(R_EBX); 5443 gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX); 5444 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff); 5445 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]); 5446 } else 5447 #endif 5448 { 5449 gen_op_movl_A0_reg(R_EBX); 5450 gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); 5451 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff); 5452 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]); 5453 if (s->aflag == 0) 5454 gen_op_andl_A0_ffff(); 5455 else 5456 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff); 5457 } 5458 gen_add_A0_ds_seg(s); 5459 gen_op_ldu_T0_A0(OT_BYTE + s->mem_index); 5460 gen_op_mov_reg_T0(OT_BYTE, R_EAX); 5461 break; 5462 case 0xb0 ... 0xb7: /* mov R, Ib */ 5463 val = insn_get(env, s, OT_BYTE); 5464 gen_op_movl_T0_im(val); 5465 gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s)); 5466 break; 5467 case 0xb8 ... 0xbf: /* mov R, Iv */ 5468 #ifdef TARGET_X86_64 5469 if (dflag == 2) { 5470 uint64_t tmp; 5471 /* 64 bit case */ 5472 tmp = cpu_ldq_code(env, s->pc); 5473 s->pc += 8; 5474 reg = (b & 7) | REX_B(s); 5475 gen_movtl_T0_im(tmp); 5476 gen_op_mov_reg_T0(OT_QUAD, reg); 5477 } else 5478 #endif 5479 { 5480 ot = dflag ? OT_LONG : OT_WORD; 5481 val = insn_get(env, s, ot); 5482 reg = (b & 7) | REX_B(s); 5483 gen_op_movl_T0_im(val); 5484 gen_op_mov_reg_T0(ot, reg); 5485 } 5486 break; 5487 5488 case 0x91 ... 0x97: /* xchg R, EAX */ 5489 ot = dflag + OT_WORD; 5490 reg = (b & 7) | REX_B(s); 5491 rm = R_EAX; 5492 goto do_xchg_reg; 5493 case 0x86: 5494 case 0x87: /* xchg Ev, Gv */ 5495 if ((b & 1) == 0) 5496 ot = OT_BYTE; 5497 else 5498 ot = dflag + OT_WORD; 5499 modrm = cpu_ldub_code(env, s->pc++); 5500 reg = ((modrm >> 3) & 7) | rex_r; 5501 mod = (modrm >> 6) & 3; 5502 if (mod == 3) { 5503 rm = (modrm & 7) | REX_B(s); 5504 do_xchg_reg: 5505 gen_op_mov_TN_reg(ot, 0, reg); 5506 gen_op_mov_TN_reg(ot, 1, rm); 5507 gen_op_mov_reg_T0(ot, rm); 5508 gen_op_mov_reg_T1(ot, reg); 5509 } else { 5510 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5511 gen_op_mov_TN_reg(ot, 0, reg); 5512 /* for xchg, lock is implicit */ 5513 if (!(prefixes & PREFIX_LOCK)) 5514 gen_helper_lock(); 5515 gen_op_ld_T1_A0(ot + s->mem_index); 5516 gen_op_st_T0_A0(ot + s->mem_index); 5517 if (!(prefixes & PREFIX_LOCK)) 5518 gen_helper_unlock(); 5519 gen_op_mov_reg_T1(ot, reg); 5520 } 5521 break; 5522 case 0xc4: /* les Gv */ 5523 if (CODE64(s)) 5524 goto illegal_op; 5525 op = R_ES; 5526 goto do_lxx; 5527 case 0xc5: /* lds Gv */ 5528 if (CODE64(s)) 5529 goto illegal_op; 5530 op = R_DS; 5531 goto do_lxx; 5532 case 0x1b2: /* lss Gv */ 5533 op = R_SS; 5534 goto do_lxx; 5535 case 0x1b4: /* lfs Gv */ 5536 op = R_FS; 5537 goto do_lxx; 5538 case 0x1b5: /* lgs Gv */ 5539 op = R_GS; 5540 do_lxx: 5541 ot = dflag ? OT_LONG : OT_WORD; 5542 modrm = cpu_ldub_code(env, s->pc++); 5543 reg = ((modrm >> 3) & 7) | rex_r; 5544 mod = (modrm >> 6) & 3; 5545 if (mod == 3) 5546 goto illegal_op; 5547 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5548 gen_op_ld_T1_A0(ot + s->mem_index); 5549 gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); 5550 /* load the segment first to handle exceptions properly */ 5551 gen_op_ldu_T0_A0(OT_WORD + s->mem_index); 5552 gen_movl_seg_T0(s, op, pc_start - s->cs_base); 5553 /* then put the data */ 5554 gen_op_mov_reg_T1(ot, reg); 5555 if (s->is_jmp) { 5556 gen_jmp_im(s->pc - s->cs_base); 5557 gen_eob(s); 5558 } 5559 break; 5560 5561 /************************/ 5562 /* shifts */ 5563 case 0xc0: 5564 case 0xc1: 5565 /* shift Ev,Ib */ 5566 shift = 2; 5567 grp2: 5568 { 5569 if ((b & 1) == 0) 5570 ot = OT_BYTE; 5571 else 5572 ot = dflag + OT_WORD; 5573 5574 modrm = cpu_ldub_code(env, s->pc++); 5575 mod = (modrm >> 6) & 3; 5576 op = (modrm >> 3) & 7; 5577 5578 if (mod != 3) { 5579 if (shift == 2) { 5580 s->rip_offset = 1; 5581 } 5582 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5583 opreg = OR_TMP0; 5584 } else { 5585 opreg = (modrm & 7) | REX_B(s); 5586 } 5587 5588 /* simpler op */ 5589 if (shift == 0) { 5590 gen_shift(s, op, ot, opreg, OR_ECX); 5591 } else { 5592 if (shift == 2) { 5593 shift = cpu_ldub_code(env, s->pc++); 5594 } 5595 gen_shifti(s, op, ot, opreg, shift); 5596 } 5597 } 5598 break; 5599 case 0xd0: 5600 case 0xd1: 5601 /* shift Ev,1 */ 5602 shift = 1; 5603 goto grp2; 5604 case 0xd2: 5605 case 0xd3: 5606 /* shift Ev,cl */ 5607 shift = 0; 5608 goto grp2; 5609 5610 case 0x1a4: /* shld imm */ 5611 op = 0; 5612 shift = 1; 5613 goto do_shiftd; 5614 case 0x1a5: /* shld cl */ 5615 op = 0; 5616 shift = 0; 5617 goto do_shiftd; 5618 case 0x1ac: /* shrd imm */ 5619 op = 1; 5620 shift = 1; 5621 goto do_shiftd; 5622 case 0x1ad: /* shrd cl */ 5623 op = 1; 5624 shift = 0; 5625 do_shiftd: 5626 ot = dflag + OT_WORD; 5627 modrm = cpu_ldub_code(env, s->pc++); 5628 mod = (modrm >> 6) & 3; 5629 rm = (modrm & 7) | REX_B(s); 5630 reg = ((modrm >> 3) & 7) | rex_r; 5631 if (mod != 3) { 5632 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5633 opreg = OR_TMP0; 5634 } else { 5635 opreg = rm; 5636 } 5637 gen_op_mov_TN_reg(ot, 1, reg); 5638 5639 if (shift) { 5640 val = cpu_ldub_code(env, s->pc++); 5641 tcg_gen_movi_tl(cpu_T3, val); 5642 } else { 5643 tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUX86State, regs[R_ECX])); 5644 } 5645 gen_shiftd_rm_T1_T3(s, ot, opreg, op); 5646 break; 5647 5648 /************************/ 5649 /* floats */ 5650 case 0xd8 ... 0xdf: 5651 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) { 5652 /* if CR0.EM or CR0.TS are set, generate an FPU exception */ 5653 /* XXX: what to do if illegal op ? */ 5654 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); 5655 break; 5656 } 5657 modrm = cpu_ldub_code(env, s->pc++); 5658 mod = (modrm >> 6) & 3; 5659 rm = modrm & 7; 5660 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 5661 if (mod != 3) { 5662 /* memory op */ 5663 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 5664 switch(op) { 5665 case 0x00 ... 0x07: /* fxxxs */ 5666 case 0x10 ... 0x17: /* fixxxl */ 5667 case 0x20 ... 0x27: /* fxxxl */ 5668 case 0x30 ... 0x37: /* fixxx */ 5669 { 5670 int op1; 5671 op1 = op & 7; 5672 5673 switch(op >> 4) { 5674 case 0: 5675 gen_op_ld_T0_A0(OT_LONG + s->mem_index); 5676 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 5677 gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32); 5678 break; 5679 case 1: 5680 gen_op_ld_T0_A0(OT_LONG + s->mem_index); 5681 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 5682 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32); 5683 break; 5684 case 2: 5685 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 5686 (s->mem_index >> 2) - 1); 5687 gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64); 5688 break; 5689 case 3: 5690 default: 5691 gen_op_lds_T0_A0(OT_WORD + s->mem_index); 5692 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 5693 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32); 5694 break; 5695 } 5696 5697 gen_helper_fp_arith_ST0_FT0(op1); 5698 if (op1 == 3) { 5699 /* fcomp needs pop */ 5700 gen_helper_fpop(cpu_env); 5701 } 5702 } 5703 break; 5704 case 0x08: /* flds */ 5705 case 0x0a: /* fsts */ 5706 case 0x0b: /* fstps */ 5707 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ 5708 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ 5709 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ 5710 switch(op & 7) { 5711 case 0: 5712 switch(op >> 4) { 5713 case 0: 5714 gen_op_ld_T0_A0(OT_LONG + s->mem_index); 5715 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 5716 gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32); 5717 break; 5718 case 1: 5719 gen_op_ld_T0_A0(OT_LONG + s->mem_index); 5720 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 5721 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32); 5722 break; 5723 case 2: 5724 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 5725 (s->mem_index >> 2) - 1); 5726 gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64); 5727 break; 5728 case 3: 5729 default: 5730 gen_op_lds_T0_A0(OT_WORD + s->mem_index); 5731 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 5732 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32); 5733 break; 5734 } 5735 break; 5736 case 1: 5737 /* XXX: the corresponding CPUID bit must be tested ! */ 5738 switch(op >> 4) { 5739 case 1: 5740 gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env); 5741 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 5742 gen_op_st_T0_A0(OT_LONG + s->mem_index); 5743 break; 5744 case 2: 5745 gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env); 5746 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 5747 (s->mem_index >> 2) - 1); 5748 break; 5749 case 3: 5750 default: 5751 gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env); 5752 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 5753 gen_op_st_T0_A0(OT_WORD + s->mem_index); 5754 break; 5755 } 5756 gen_helper_fpop(cpu_env); 5757 break; 5758 default: 5759 switch(op >> 4) { 5760 case 0: 5761 gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env); 5762 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 5763 gen_op_st_T0_A0(OT_LONG + s->mem_index); 5764 break; 5765 case 1: 5766 gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env); 5767 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 5768 gen_op_st_T0_A0(OT_LONG + s->mem_index); 5769 break; 5770 case 2: 5771 gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env); 5772 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 5773 (s->mem_index >> 2) - 1); 5774 break; 5775 case 3: 5776 default: 5777 gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env); 5778 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 5779 gen_op_st_T0_A0(OT_WORD + s->mem_index); 5780 break; 5781 } 5782 if ((op & 7) == 3) 5783 gen_helper_fpop(cpu_env); 5784 break; 5785 } 5786 break; 5787 case 0x0c: /* fldenv mem */ 5788 gen_update_cc_op(s); 5789 gen_jmp_im(pc_start - s->cs_base); 5790 gen_helper_fldenv(cpu_env, 5791 cpu_A0, tcg_const_i32(s->dflag)); 5792 break; 5793 case 0x0d: /* fldcw mem */ 5794 gen_op_ld_T0_A0(OT_WORD + s->mem_index); 5795 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 5796 gen_helper_fldcw(cpu_env, cpu_tmp2_i32); 5797 break; 5798 case 0x0e: /* fnstenv mem */ 5799 gen_update_cc_op(s); 5800 gen_jmp_im(pc_start - s->cs_base); 5801 gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag)); 5802 break; 5803 case 0x0f: /* fnstcw mem */ 5804 gen_helper_fnstcw(cpu_tmp2_i32, cpu_env); 5805 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 5806 gen_op_st_T0_A0(OT_WORD + s->mem_index); 5807 break; 5808 case 0x1d: /* fldt mem */ 5809 gen_update_cc_op(s); 5810 gen_jmp_im(pc_start - s->cs_base); 5811 gen_helper_fldt_ST0(cpu_env, cpu_A0); 5812 break; 5813 case 0x1f: /* fstpt mem */ 5814 gen_update_cc_op(s); 5815 gen_jmp_im(pc_start - s->cs_base); 5816 gen_helper_fstt_ST0(cpu_env, cpu_A0); 5817 gen_helper_fpop(cpu_env); 5818 break; 5819 case 0x2c: /* frstor mem */ 5820 gen_update_cc_op(s); 5821 gen_jmp_im(pc_start - s->cs_base); 5822 gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(s->dflag)); 5823 break; 5824 case 0x2e: /* fnsave mem */ 5825 gen_update_cc_op(s); 5826 gen_jmp_im(pc_start - s->cs_base); 5827 gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(s->dflag)); 5828 break; 5829 case 0x2f: /* fnstsw mem */ 5830 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env); 5831 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 5832 gen_op_st_T0_A0(OT_WORD + s->mem_index); 5833 break; 5834 case 0x3c: /* fbld */ 5835 gen_update_cc_op(s); 5836 gen_jmp_im(pc_start - s->cs_base); 5837 gen_helper_fbld_ST0(cpu_env, cpu_A0); 5838 break; 5839 case 0x3e: /* fbstp */ 5840 gen_update_cc_op(s); 5841 gen_jmp_im(pc_start - s->cs_base); 5842 gen_helper_fbst_ST0(cpu_env, cpu_A0); 5843 gen_helper_fpop(cpu_env); 5844 break; 5845 case 0x3d: /* fildll */ 5846 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 5847 (s->mem_index >> 2) - 1); 5848 gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64); 5849 break; 5850 case 0x3f: /* fistpll */ 5851 gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env); 5852 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 5853 (s->mem_index >> 2) - 1); 5854 gen_helper_fpop(cpu_env); 5855 break; 5856 default: 5857 goto illegal_op; 5858 } 5859 } else { 5860 /* register float ops */ 5861 opreg = rm; 5862 5863 switch(op) { 5864 case 0x08: /* fld sti */ 5865 gen_helper_fpush(cpu_env); 5866 gen_helper_fmov_ST0_STN(cpu_env, 5867 tcg_const_i32((opreg + 1) & 7)); 5868 break; 5869 case 0x09: /* fxchg sti */ 5870 case 0x29: /* fxchg4 sti, undocumented op */ 5871 case 0x39: /* fxchg7 sti, undocumented op */ 5872 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg)); 5873 break; 5874 case 0x0a: /* grp d9/2 */ 5875 switch(rm) { 5876 case 0: /* fnop */ 5877 /* check exceptions (FreeBSD FPU probe) */ 5878 gen_update_cc_op(s); 5879 gen_jmp_im(pc_start - s->cs_base); 5880 gen_helper_fwait(cpu_env); 5881 break; 5882 default: 5883 goto illegal_op; 5884 } 5885 break; 5886 case 0x0c: /* grp d9/4 */ 5887 switch(rm) { 5888 case 0: /* fchs */ 5889 gen_helper_fchs_ST0(cpu_env); 5890 break; 5891 case 1: /* fabs */ 5892 gen_helper_fabs_ST0(cpu_env); 5893 break; 5894 case 4: /* ftst */ 5895 gen_helper_fldz_FT0(cpu_env); 5896 gen_helper_fcom_ST0_FT0(cpu_env); 5897 break; 5898 case 5: /* fxam */ 5899 gen_helper_fxam_ST0(cpu_env); 5900 break; 5901 default: 5902 goto illegal_op; 5903 } 5904 break; 5905 case 0x0d: /* grp d9/5 */ 5906 { 5907 switch(rm) { 5908 case 0: 5909 gen_helper_fpush(cpu_env); 5910 gen_helper_fld1_ST0(cpu_env); 5911 break; 5912 case 1: 5913 gen_helper_fpush(cpu_env); 5914 gen_helper_fldl2t_ST0(cpu_env); 5915 break; 5916 case 2: 5917 gen_helper_fpush(cpu_env); 5918 gen_helper_fldl2e_ST0(cpu_env); 5919 break; 5920 case 3: 5921 gen_helper_fpush(cpu_env); 5922 gen_helper_fldpi_ST0(cpu_env); 5923 break; 5924 case 4: 5925 gen_helper_fpush(cpu_env); 5926 gen_helper_fldlg2_ST0(cpu_env); 5927 break; 5928 case 5: 5929 gen_helper_fpush(cpu_env); 5930 gen_helper_fldln2_ST0(cpu_env); 5931 break; 5932 case 6: 5933 gen_helper_fpush(cpu_env); 5934 gen_helper_fldz_ST0(cpu_env); 5935 break; 5936 default: 5937 goto illegal_op; 5938 } 5939 } 5940 break; 5941 case 0x0e: /* grp d9/6 */ 5942 switch(rm) { 5943 case 0: /* f2xm1 */ 5944 gen_helper_f2xm1(cpu_env); 5945 break; 5946 case 1: /* fyl2x */ 5947 gen_helper_fyl2x(cpu_env); 5948 break; 5949 case 2: /* fptan */ 5950 gen_helper_fptan(cpu_env); 5951 break; 5952 case 3: /* fpatan */ 5953 gen_helper_fpatan(cpu_env); 5954 break; 5955 case 4: /* fxtract */ 5956 gen_helper_fxtract(cpu_env); 5957 break; 5958 case 5: /* fprem1 */ 5959 gen_helper_fprem1(cpu_env); 5960 break; 5961 case 6: /* fdecstp */ 5962 gen_helper_fdecstp(cpu_env); 5963 break; 5964 default: 5965 case 7: /* fincstp */ 5966 gen_helper_fincstp(cpu_env); 5967 break; 5968 } 5969 break; 5970 case 0x0f: /* grp d9/7 */ 5971 switch(rm) { 5972 case 0: /* fprem */ 5973 gen_helper_fprem(cpu_env); 5974 break; 5975 case 1: /* fyl2xp1 */ 5976 gen_helper_fyl2xp1(cpu_env); 5977 break; 5978 case 2: /* fsqrt */ 5979 gen_helper_fsqrt(cpu_env); 5980 break; 5981 case 3: /* fsincos */ 5982 gen_helper_fsincos(cpu_env); 5983 break; 5984 case 5: /* fscale */ 5985 gen_helper_fscale(cpu_env); 5986 break; 5987 case 4: /* frndint */ 5988 gen_helper_frndint(cpu_env); 5989 break; 5990 case 6: /* fsin */ 5991 gen_helper_fsin(cpu_env); 5992 break; 5993 default: 5994 case 7: /* fcos */ 5995 gen_helper_fcos(cpu_env); 5996 break; 5997 } 5998 break; 5999 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */ 6000 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */ 6001 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */ 6002 { 6003 int op1; 6004 6005 op1 = op & 7; 6006 if (op >= 0x20) { 6007 gen_helper_fp_arith_STN_ST0(op1, opreg); 6008 if (op >= 0x30) 6009 gen_helper_fpop(cpu_env); 6010 } else { 6011 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6012 gen_helper_fp_arith_ST0_FT0(op1); 6013 } 6014 } 6015 break; 6016 case 0x02: /* fcom */ 6017 case 0x22: /* fcom2, undocumented op */ 6018 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6019 gen_helper_fcom_ST0_FT0(cpu_env); 6020 break; 6021 case 0x03: /* fcomp */ 6022 case 0x23: /* fcomp3, undocumented op */ 6023 case 0x32: /* fcomp5, undocumented op */ 6024 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6025 gen_helper_fcom_ST0_FT0(cpu_env); 6026 gen_helper_fpop(cpu_env); 6027 break; 6028 case 0x15: /* da/5 */ 6029 switch(rm) { 6030 case 1: /* fucompp */ 6031 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1)); 6032 gen_helper_fucom_ST0_FT0(cpu_env); 6033 gen_helper_fpop(cpu_env); 6034 gen_helper_fpop(cpu_env); 6035 break; 6036 default: 6037 goto illegal_op; 6038 } 6039 break; 6040 case 0x1c: 6041 switch(rm) { 6042 case 0: /* feni (287 only, just do nop here) */ 6043 break; 6044 case 1: /* fdisi (287 only, just do nop here) */ 6045 break; 6046 case 2: /* fclex */ 6047 gen_helper_fclex(cpu_env); 6048 break; 6049 case 3: /* fninit */ 6050 gen_helper_fninit(cpu_env); 6051 break; 6052 case 4: /* fsetpm (287 only, just do nop here) */ 6053 break; 6054 default: 6055 goto illegal_op; 6056 } 6057 break; 6058 case 0x1d: /* fucomi */ 6059 gen_update_cc_op(s); 6060 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6061 gen_helper_fucomi_ST0_FT0(cpu_env); 6062 set_cc_op(s, CC_OP_EFLAGS); 6063 break; 6064 case 0x1e: /* fcomi */ 6065 gen_update_cc_op(s); 6066 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6067 gen_helper_fcomi_ST0_FT0(cpu_env); 6068 set_cc_op(s, CC_OP_EFLAGS); 6069 break; 6070 case 0x28: /* ffree sti */ 6071 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg)); 6072 break; 6073 case 0x2a: /* fst sti */ 6074 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg)); 6075 break; 6076 case 0x2b: /* fstp sti */ 6077 case 0x0b: /* fstp1 sti, undocumented op */ 6078 case 0x3a: /* fstp8 sti, undocumented op */ 6079 case 0x3b: /* fstp9 sti, undocumented op */ 6080 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg)); 6081 gen_helper_fpop(cpu_env); 6082 break; 6083 case 0x2c: /* fucom st(i) */ 6084 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6085 gen_helper_fucom_ST0_FT0(cpu_env); 6086 break; 6087 case 0x2d: /* fucomp st(i) */ 6088 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6089 gen_helper_fucom_ST0_FT0(cpu_env); 6090 gen_helper_fpop(cpu_env); 6091 break; 6092 case 0x33: /* de/3 */ 6093 switch(rm) { 6094 case 1: /* fcompp */ 6095 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1)); 6096 gen_helper_fcom_ST0_FT0(cpu_env); 6097 gen_helper_fpop(cpu_env); 6098 gen_helper_fpop(cpu_env); 6099 break; 6100 default: 6101 goto illegal_op; 6102 } 6103 break; 6104 case 0x38: /* ffreep sti, undocumented op */ 6105 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg)); 6106 gen_helper_fpop(cpu_env); 6107 break; 6108 case 0x3c: /* df/4 */ 6109 switch(rm) { 6110 case 0: 6111 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env); 6112 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); 6113 gen_op_mov_reg_T0(OT_WORD, R_EAX); 6114 break; 6115 default: 6116 goto illegal_op; 6117 } 6118 break; 6119 case 0x3d: /* fucomip */ 6120 gen_update_cc_op(s); 6121 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6122 gen_helper_fucomi_ST0_FT0(cpu_env); 6123 gen_helper_fpop(cpu_env); 6124 set_cc_op(s, CC_OP_EFLAGS); 6125 break; 6126 case 0x3e: /* fcomip */ 6127 gen_update_cc_op(s); 6128 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg)); 6129 gen_helper_fcomi_ST0_FT0(cpu_env); 6130 gen_helper_fpop(cpu_env); 6131 set_cc_op(s, CC_OP_EFLAGS); 6132 break; 6133 case 0x10 ... 0x13: /* fcmovxx */ 6134 case 0x18 ... 0x1b: 6135 { 6136 int op1, l1; 6137 static const uint8_t fcmov_cc[8] = { 6138 (JCC_B << 1), 6139 (JCC_Z << 1), 6140 (JCC_BE << 1), 6141 (JCC_P << 1), 6142 }; 6143 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1); 6144 l1 = gen_new_label(); 6145 gen_jcc1(s, op1, l1); 6146 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg)); 6147 gen_set_label(l1); 6148 } 6149 break; 6150 default: 6151 goto illegal_op; 6152 } 6153 } 6154 break; 6155 /************************/ 6156 /* string ops */ 6157 6158 case 0xa4: /* movsS */ 6159 case 0xa5: 6160 if ((b & 1) == 0) 6161 ot = OT_BYTE; 6162 else 6163 ot = dflag + OT_WORD; 6164 6165 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6166 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); 6167 } else { 6168 gen_movs(s, ot); 6169 } 6170 break; 6171 6172 case 0xaa: /* stosS */ 6173 case 0xab: 6174 if ((b & 1) == 0) 6175 ot = OT_BYTE; 6176 else 6177 ot = dflag + OT_WORD; 6178 6179 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6180 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); 6181 } else { 6182 gen_stos(s, ot); 6183 } 6184 break; 6185 case 0xac: /* lodsS */ 6186 case 0xad: 6187 if ((b & 1) == 0) 6188 ot = OT_BYTE; 6189 else 6190 ot = dflag + OT_WORD; 6191 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6192 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); 6193 } else { 6194 gen_lods(s, ot); 6195 } 6196 break; 6197 case 0xae: /* scasS */ 6198 case 0xaf: 6199 if ((b & 1) == 0) 6200 ot = OT_BYTE; 6201 else 6202 ot = dflag + OT_WORD; 6203 if (prefixes & PREFIX_REPNZ) { 6204 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1); 6205 } else if (prefixes & PREFIX_REPZ) { 6206 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0); 6207 } else { 6208 gen_scas(s, ot); 6209 set_cc_op(s, CC_OP_SUBB + ot); 6210 } 6211 break; 6212 6213 case 0xa6: /* cmpsS */ 6214 case 0xa7: 6215 if ((b & 1) == 0) 6216 ot = OT_BYTE; 6217 else 6218 ot = dflag + OT_WORD; 6219 if (prefixes & PREFIX_REPNZ) { 6220 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1); 6221 } else if (prefixes & PREFIX_REPZ) { 6222 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0); 6223 } else { 6224 gen_cmps(s, ot); 6225 set_cc_op(s, CC_OP_SUBB + ot); 6226 } 6227 break; 6228 case 0x6c: /* insS */ 6229 case 0x6d: 6230 if ((b & 1) == 0) 6231 ot = OT_BYTE; 6232 else 6233 ot = dflag ? OT_LONG : OT_WORD; 6234 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); 6235 gen_op_andl_T0_ffff(); 6236 gen_check_io(s, ot, pc_start - s->cs_base, 6237 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4); 6238 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6239 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); 6240 } else { 6241 gen_ins(s, ot); 6242 if (use_icount) { 6243 gen_jmp(s, s->pc - s->cs_base); 6244 } 6245 } 6246 break; 6247 case 0x6e: /* outsS */ 6248 case 0x6f: 6249 if ((b & 1) == 0) 6250 ot = OT_BYTE; 6251 else 6252 ot = dflag ? OT_LONG : OT_WORD; 6253 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); 6254 gen_op_andl_T0_ffff(); 6255 gen_check_io(s, ot, pc_start - s->cs_base, 6256 svm_is_rep(prefixes) | 4); 6257 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { 6258 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); 6259 } else { 6260 gen_outs(s, ot); 6261 if (use_icount) { 6262 gen_jmp(s, s->pc - s->cs_base); 6263 } 6264 } 6265 break; 6266 6267 /************************/ 6268 /* port I/O */ 6269 6270 case 0xe4: 6271 case 0xe5: 6272 if ((b & 1) == 0) 6273 ot = OT_BYTE; 6274 else 6275 ot = dflag ? OT_LONG : OT_WORD; 6276 val = cpu_ldub_code(env, s->pc++); 6277 gen_op_movl_T0_im(val); 6278 gen_check_io(s, ot, pc_start - s->cs_base, 6279 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes)); 6280 if (use_icount) 6281 gen_io_start(); 6282 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 6283 gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32); 6284 gen_op_mov_reg_T1(ot, R_EAX); 6285 if (use_icount) { 6286 gen_io_end(); 6287 gen_jmp(s, s->pc - s->cs_base); 6288 } 6289 break; 6290 case 0xe6: 6291 case 0xe7: 6292 if ((b & 1) == 0) 6293 ot = OT_BYTE; 6294 else 6295 ot = dflag ? OT_LONG : OT_WORD; 6296 val = cpu_ldub_code(env, s->pc++); 6297 gen_op_movl_T0_im(val); 6298 gen_check_io(s, ot, pc_start - s->cs_base, 6299 svm_is_rep(prefixes)); 6300 gen_op_mov_TN_reg(ot, 1, R_EAX); 6301 6302 if (use_icount) 6303 gen_io_start(); 6304 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 6305 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); 6306 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]); 6307 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32); 6308 if (use_icount) { 6309 gen_io_end(); 6310 gen_jmp(s, s->pc - s->cs_base); 6311 } 6312 break; 6313 case 0xec: 6314 case 0xed: 6315 if ((b & 1) == 0) 6316 ot = OT_BYTE; 6317 else 6318 ot = dflag ? OT_LONG : OT_WORD; 6319 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); 6320 gen_op_andl_T0_ffff(); 6321 gen_check_io(s, ot, pc_start - s->cs_base, 6322 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes)); 6323 if (use_icount) 6324 gen_io_start(); 6325 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 6326 gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32); 6327 gen_op_mov_reg_T1(ot, R_EAX); 6328 if (use_icount) { 6329 gen_io_end(); 6330 gen_jmp(s, s->pc - s->cs_base); 6331 } 6332 break; 6333 case 0xee: 6334 case 0xef: 6335 if ((b & 1) == 0) 6336 ot = OT_BYTE; 6337 else 6338 ot = dflag ? OT_LONG : OT_WORD; 6339 gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); 6340 gen_op_andl_T0_ffff(); 6341 gen_check_io(s, ot, pc_start - s->cs_base, 6342 svm_is_rep(prefixes)); 6343 gen_op_mov_TN_reg(ot, 1, R_EAX); 6344 6345 if (use_icount) 6346 gen_io_start(); 6347 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 6348 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); 6349 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]); 6350 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32); 6351 if (use_icount) { 6352 gen_io_end(); 6353 gen_jmp(s, s->pc - s->cs_base); 6354 } 6355 break; 6356 6357 /************************/ 6358 /* control */ 6359 case 0xc2: /* ret im */ 6360 val = cpu_ldsw_code(env, s->pc); 6361 s->pc += 2; 6362 gen_pop_T0(s); 6363 if (CODE64(s) && s->dflag) 6364 s->dflag = 2; 6365 gen_stack_update(s, val + (2 << s->dflag)); 6366 if (s->dflag == 0) 6367 gen_op_andl_T0_ffff(); 6368 gen_op_jmp_T0(); 6369 gen_eob(s); 6370 break; 6371 case 0xc3: /* ret */ 6372 gen_pop_T0(s); 6373 gen_pop_update(s); 6374 if (s->dflag == 0) 6375 gen_op_andl_T0_ffff(); 6376 gen_op_jmp_T0(); 6377 gen_eob(s); 6378 break; 6379 case 0xca: /* lret im */ 6380 val = cpu_ldsw_code(env, s->pc); 6381 s->pc += 2; 6382 do_lret: 6383 if (s->pe && !s->vm86) { 6384 gen_update_cc_op(s); 6385 gen_jmp_im(pc_start - s->cs_base); 6386 gen_helper_lret_protected(cpu_env, tcg_const_i32(s->dflag), 6387 tcg_const_i32(val)); 6388 } else { 6389 gen_stack_A0(s); 6390 /* pop offset */ 6391 gen_op_ld_T0_A0(1 + s->dflag + s->mem_index); 6392 if (s->dflag == 0) 6393 gen_op_andl_T0_ffff(); 6394 /* NOTE: keeping EIP updated is not a problem in case of 6395 exception */ 6396 gen_op_jmp_T0(); 6397 /* pop selector */ 6398 gen_op_addl_A0_im(2 << s->dflag); 6399 gen_op_ld_T0_A0(1 + s->dflag + s->mem_index); 6400 gen_op_movl_seg_T0_vm(R_CS); 6401 /* add stack offset */ 6402 gen_stack_update(s, val + (4 << s->dflag)); 6403 } 6404 gen_eob(s); 6405 break; 6406 case 0xcb: /* lret */ 6407 val = 0; 6408 goto do_lret; 6409 case 0xcf: /* iret */ 6410 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET); 6411 if (!s->pe) { 6412 /* real mode */ 6413 gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag)); 6414 set_cc_op(s, CC_OP_EFLAGS); 6415 } else if (s->vm86) { 6416 if (s->iopl != 3) { 6417 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6418 } else { 6419 gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag)); 6420 set_cc_op(s, CC_OP_EFLAGS); 6421 } 6422 } else { 6423 gen_update_cc_op(s); 6424 gen_jmp_im(pc_start - s->cs_base); 6425 gen_helper_iret_protected(cpu_env, tcg_const_i32(s->dflag), 6426 tcg_const_i32(s->pc - s->cs_base)); 6427 set_cc_op(s, CC_OP_EFLAGS); 6428 } 6429 gen_eob(s); 6430 break; 6431 case 0xe8: /* call im */ 6432 { 6433 if (dflag) 6434 tval = (int32_t)insn_get(env, s, OT_LONG); 6435 else 6436 tval = (int16_t)insn_get(env, s, OT_WORD); 6437 next_eip = s->pc - s->cs_base; 6438 tval += next_eip; 6439 if (s->dflag == 0) 6440 tval &= 0xffff; 6441 gen_movtl_T0_im(next_eip); 6442 gen_push_T0(s); 6443 gen_jmp(s, tval); 6444 } 6445 break; 6446 case 0x9a: /* lcall im */ 6447 { 6448 unsigned int selector, offset; 6449 6450 if (CODE64(s)) 6451 goto illegal_op; 6452 ot = dflag ? OT_LONG : OT_WORD; 6453 offset = insn_get(env, s, ot); 6454 selector = insn_get(env, s, OT_WORD); 6455 6456 gen_op_movl_T0_im(selector); 6457 gen_op_movl_T1_imu(offset); 6458 } 6459 goto do_lcall; 6460 case 0xe9: /* jmp im */ 6461 if (dflag) 6462 tval = (int32_t)insn_get(env, s, OT_LONG); 6463 else 6464 tval = (int16_t)insn_get(env, s, OT_WORD); 6465 tval += s->pc - s->cs_base; 6466 if (s->dflag == 0) 6467 tval &= 0xffff; 6468 else if(!CODE64(s)) 6469 tval &= 0xffffffff; 6470 gen_jmp(s, tval); 6471 break; 6472 case 0xea: /* ljmp im */ 6473 { 6474 unsigned int selector, offset; 6475 6476 if (CODE64(s)) 6477 goto illegal_op; 6478 ot = dflag ? OT_LONG : OT_WORD; 6479 offset = insn_get(env, s, ot); 6480 selector = insn_get(env, s, OT_WORD); 6481 6482 gen_op_movl_T0_im(selector); 6483 gen_op_movl_T1_imu(offset); 6484 } 6485 goto do_ljmp; 6486 case 0xeb: /* jmp Jb */ 6487 tval = (int8_t)insn_get(env, s, OT_BYTE); 6488 tval += s->pc - s->cs_base; 6489 if (s->dflag == 0) 6490 tval &= 0xffff; 6491 gen_jmp(s, tval); 6492 break; 6493 case 0x70 ... 0x7f: /* jcc Jb */ 6494 tval = (int8_t)insn_get(env, s, OT_BYTE); 6495 goto do_jcc; 6496 case 0x180 ... 0x18f: /* jcc Jv */ 6497 if (dflag) { 6498 tval = (int32_t)insn_get(env, s, OT_LONG); 6499 } else { 6500 tval = (int16_t)insn_get(env, s, OT_WORD); 6501 } 6502 do_jcc: 6503 next_eip = s->pc - s->cs_base; 6504 tval += next_eip; 6505 if (s->dflag == 0) 6506 tval &= 0xffff; 6507 gen_jcc(s, b, tval, next_eip); 6508 break; 6509 6510 case 0x190 ... 0x19f: /* setcc Gv */ 6511 modrm = cpu_ldub_code(env, s->pc++); 6512 gen_setcc(s, b); 6513 gen_ldst_modrm(env, s, modrm, OT_BYTE, OR_TMP0, 1); 6514 break; 6515 case 0x140 ... 0x14f: /* cmov Gv, Ev */ 6516 { 6517 int l1; 6518 TCGv t0; 6519 6520 ot = dflag + OT_WORD; 6521 modrm = cpu_ldub_code(env, s->pc++); 6522 reg = ((modrm >> 3) & 7) | rex_r; 6523 mod = (modrm >> 6) & 3; 6524 t0 = tcg_temp_local_new(); 6525 if (mod != 3) { 6526 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 6527 gen_op_ld_v(ot + s->mem_index, t0, cpu_A0); 6528 } else { 6529 rm = (modrm & 7) | REX_B(s); 6530 gen_op_mov_v_reg(ot, t0, rm); 6531 } 6532 #ifdef TARGET_X86_64 6533 if (ot == OT_LONG) { 6534 /* XXX: specific Intel behaviour ? */ 6535 l1 = gen_new_label(); 6536 gen_jcc1(s, b ^ 1, l1); 6537 tcg_gen_st32_tl(t0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_L_OFFSET); 6538 gen_set_label(l1); 6539 tcg_gen_movi_tl(cpu_tmp0, 0); 6540 tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, regs[reg]) + REG_LH_OFFSET); 6541 } else 6542 #endif 6543 { 6544 l1 = gen_new_label(); 6545 gen_jcc1(s, b ^ 1, l1); 6546 gen_op_mov_reg_v(ot, reg, t0); 6547 gen_set_label(l1); 6548 } 6549 tcg_temp_free(t0); 6550 } 6551 break; 6552 6553 /************************/ 6554 /* flags */ 6555 case 0x9c: /* pushf */ 6556 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF); 6557 if (s->vm86 && s->iopl != 3) { 6558 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6559 } else { 6560 gen_update_cc_op(s); 6561 gen_helper_read_eflags(cpu_T[0], cpu_env); 6562 gen_push_T0(s); 6563 } 6564 break; 6565 case 0x9d: /* popf */ 6566 gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF); 6567 if (s->vm86 && s->iopl != 3) { 6568 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6569 } else { 6570 gen_pop_T0(s); 6571 if (s->cpl == 0) { 6572 if (s->dflag) { 6573 gen_helper_write_eflags(cpu_env, cpu_T[0], 6574 tcg_const_i32((TF_MASK | AC_MASK | 6575 ID_MASK | NT_MASK | 6576 IF_MASK | 6577 IOPL_MASK))); 6578 } else { 6579 gen_helper_write_eflags(cpu_env, cpu_T[0], 6580 tcg_const_i32((TF_MASK | AC_MASK | 6581 ID_MASK | NT_MASK | 6582 IF_MASK | IOPL_MASK) 6583 & 0xffff)); 6584 } 6585 } else { 6586 if (s->cpl <= s->iopl) { 6587 if (s->dflag) { 6588 gen_helper_write_eflags(cpu_env, cpu_T[0], 6589 tcg_const_i32((TF_MASK | 6590 AC_MASK | 6591 ID_MASK | 6592 NT_MASK | 6593 IF_MASK))); 6594 } else { 6595 gen_helper_write_eflags(cpu_env, cpu_T[0], 6596 tcg_const_i32((TF_MASK | 6597 AC_MASK | 6598 ID_MASK | 6599 NT_MASK | 6600 IF_MASK) 6601 & 0xffff)); 6602 } 6603 } else { 6604 if (s->dflag) { 6605 gen_helper_write_eflags(cpu_env, cpu_T[0], 6606 tcg_const_i32((TF_MASK | AC_MASK | 6607 ID_MASK | NT_MASK))); 6608 } else { 6609 gen_helper_write_eflags(cpu_env, cpu_T[0], 6610 tcg_const_i32((TF_MASK | AC_MASK | 6611 ID_MASK | NT_MASK) 6612 & 0xffff)); 6613 } 6614 } 6615 } 6616 gen_pop_update(s); 6617 set_cc_op(s, CC_OP_EFLAGS); 6618 /* abort translation because TF flag may change */ 6619 gen_jmp_im(s->pc - s->cs_base); 6620 gen_eob(s); 6621 } 6622 break; 6623 case 0x9e: /* sahf */ 6624 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) 6625 goto illegal_op; 6626 gen_op_mov_TN_reg(OT_BYTE, 0, R_AH); 6627 gen_compute_eflags(s); 6628 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O); 6629 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C); 6630 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]); 6631 break; 6632 case 0x9f: /* lahf */ 6633 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) 6634 goto illegal_op; 6635 gen_compute_eflags(s); 6636 /* Note: gen_compute_eflags() only gives the condition codes */ 6637 tcg_gen_ori_tl(cpu_T[0], cpu_cc_src, 0x02); 6638 gen_op_mov_reg_T0(OT_BYTE, R_AH); 6639 break; 6640 case 0xf5: /* cmc */ 6641 gen_compute_eflags(s); 6642 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C); 6643 break; 6644 case 0xf8: /* clc */ 6645 gen_compute_eflags(s); 6646 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C); 6647 break; 6648 case 0xf9: /* stc */ 6649 gen_compute_eflags(s); 6650 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C); 6651 break; 6652 case 0xfc: /* cld */ 6653 tcg_gen_movi_i32(cpu_tmp2_i32, 1); 6654 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df)); 6655 break; 6656 case 0xfd: /* std */ 6657 tcg_gen_movi_i32(cpu_tmp2_i32, -1); 6658 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df)); 6659 break; 6660 6661 /************************/ 6662 /* bit operations */ 6663 case 0x1ba: /* bt/bts/btr/btc Gv, im */ 6664 ot = dflag + OT_WORD; 6665 modrm = cpu_ldub_code(env, s->pc++); 6666 op = (modrm >> 3) & 7; 6667 mod = (modrm >> 6) & 3; 6668 rm = (modrm & 7) | REX_B(s); 6669 if (mod != 3) { 6670 s->rip_offset = 1; 6671 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 6672 gen_op_ld_T0_A0(ot + s->mem_index); 6673 } else { 6674 gen_op_mov_TN_reg(ot, 0, rm); 6675 } 6676 /* load shift */ 6677 val = cpu_ldub_code(env, s->pc++); 6678 gen_op_movl_T1_im(val); 6679 if (op < 4) 6680 goto illegal_op; 6681 op -= 4; 6682 goto bt_op; 6683 case 0x1a3: /* bt Gv, Ev */ 6684 op = 0; 6685 goto do_btx; 6686 case 0x1ab: /* bts */ 6687 op = 1; 6688 goto do_btx; 6689 case 0x1b3: /* btr */ 6690 op = 2; 6691 goto do_btx; 6692 case 0x1bb: /* btc */ 6693 op = 3; 6694 do_btx: 6695 ot = dflag + OT_WORD; 6696 modrm = cpu_ldub_code(env, s->pc++); 6697 reg = ((modrm >> 3) & 7) | rex_r; 6698 mod = (modrm >> 6) & 3; 6699 rm = (modrm & 7) | REX_B(s); 6700 gen_op_mov_TN_reg(OT_LONG, 1, reg); 6701 if (mod != 3) { 6702 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 6703 /* specific case: we need to add a displacement */ 6704 gen_exts(ot, cpu_T[1]); 6705 tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot); 6706 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot); 6707 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); 6708 gen_op_ld_T0_A0(ot + s->mem_index); 6709 } else { 6710 gen_op_mov_TN_reg(ot, 0, rm); 6711 } 6712 bt_op: 6713 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1); 6714 switch(op) { 6715 case 0: 6716 tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]); 6717 tcg_gen_movi_tl(cpu_cc_dst, 0); 6718 break; 6719 case 1: 6720 tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]); 6721 tcg_gen_movi_tl(cpu_tmp0, 1); 6722 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]); 6723 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0); 6724 break; 6725 case 2: 6726 tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]); 6727 tcg_gen_movi_tl(cpu_tmp0, 1); 6728 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]); 6729 tcg_gen_not_tl(cpu_tmp0, cpu_tmp0); 6730 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0); 6731 break; 6732 default: 6733 case 3: 6734 tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]); 6735 tcg_gen_movi_tl(cpu_tmp0, 1); 6736 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]); 6737 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0); 6738 break; 6739 } 6740 set_cc_op(s, CC_OP_SARB + ot); 6741 if (op != 0) { 6742 if (mod != 3) 6743 gen_op_st_T0_A0(ot + s->mem_index); 6744 else 6745 gen_op_mov_reg_T0(ot, rm); 6746 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4); 6747 tcg_gen_movi_tl(cpu_cc_dst, 0); 6748 } 6749 break; 6750 case 0x1bc: /* bsf */ 6751 case 0x1bd: /* bsr */ 6752 { 6753 int label1; 6754 TCGv t0; 6755 6756 ot = dflag + OT_WORD; 6757 modrm = cpu_ldub_code(env, s->pc++); 6758 reg = ((modrm >> 3) & 7) | rex_r; 6759 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 6760 gen_extu(ot, cpu_T[0]); 6761 label1 = gen_new_label(); 6762 tcg_gen_movi_tl(cpu_cc_dst, 0); 6763 t0 = tcg_temp_local_new(); 6764 tcg_gen_mov_tl(t0, cpu_T[0]); 6765 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1); 6766 if (b & 1) { 6767 gen_helper_bsr(cpu_T[0], t0); 6768 } else { 6769 gen_helper_bsf(cpu_T[0], t0); 6770 } 6771 gen_op_mov_reg_T0(ot, reg); 6772 tcg_gen_movi_tl(cpu_cc_dst, 1); 6773 gen_set_label(label1); 6774 set_cc_op(s, CC_OP_LOGICB + ot); 6775 tcg_temp_free(t0); 6776 } 6777 break; 6778 /************************/ 6779 /* bcd */ 6780 case 0x27: /* daa */ 6781 if (CODE64(s)) 6782 goto illegal_op; 6783 gen_update_cc_op(s); 6784 gen_helper_daa(cpu_env); 6785 set_cc_op(s, CC_OP_EFLAGS); 6786 break; 6787 case 0x2f: /* das */ 6788 if (CODE64(s)) 6789 goto illegal_op; 6790 gen_update_cc_op(s); 6791 gen_helper_das(cpu_env); 6792 set_cc_op(s, CC_OP_EFLAGS); 6793 break; 6794 case 0x37: /* aaa */ 6795 if (CODE64(s)) 6796 goto illegal_op; 6797 gen_update_cc_op(s); 6798 gen_helper_aaa(cpu_env); 6799 set_cc_op(s, CC_OP_EFLAGS); 6800 break; 6801 case 0x3f: /* aas */ 6802 if (CODE64(s)) 6803 goto illegal_op; 6804 gen_update_cc_op(s); 6805 gen_helper_aas(cpu_env); 6806 set_cc_op(s, CC_OP_EFLAGS); 6807 break; 6808 case 0xd4: /* aam */ 6809 if (CODE64(s)) 6810 goto illegal_op; 6811 val = cpu_ldub_code(env, s->pc++); 6812 if (val == 0) { 6813 gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base); 6814 } else { 6815 gen_helper_aam(cpu_env, tcg_const_i32(val)); 6816 set_cc_op(s, CC_OP_LOGICB); 6817 } 6818 break; 6819 case 0xd5: /* aad */ 6820 if (CODE64(s)) 6821 goto illegal_op; 6822 val = cpu_ldub_code(env, s->pc++); 6823 gen_helper_aad(cpu_env, tcg_const_i32(val)); 6824 set_cc_op(s, CC_OP_LOGICB); 6825 break; 6826 /************************/ 6827 /* misc */ 6828 case 0x90: /* nop */ 6829 /* XXX: xchg + rex handling */ 6830 /* XXX: correct lock test for all insn */ 6831 if (prefixes & PREFIX_LOCK) { 6832 goto illegal_op; 6833 } 6834 if (prefixes & PREFIX_REPZ) { 6835 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE); 6836 } 6837 break; 6838 case 0x9b: /* fwait */ 6839 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == 6840 (HF_MP_MASK | HF_TS_MASK)) { 6841 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); 6842 } else { 6843 gen_update_cc_op(s); 6844 gen_jmp_im(pc_start - s->cs_base); 6845 gen_helper_fwait(cpu_env); 6846 } 6847 break; 6848 case 0xcc: /* int3 */ 6849 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base); 6850 break; 6851 case 0xcd: /* int N */ 6852 val = cpu_ldub_code(env, s->pc++); 6853 if (s->vm86 && s->iopl != 3) { 6854 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6855 } else { 6856 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base); 6857 } 6858 break; 6859 case 0xce: /* into */ 6860 if (CODE64(s)) 6861 goto illegal_op; 6862 gen_update_cc_op(s); 6863 gen_jmp_im(pc_start - s->cs_base); 6864 gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start)); 6865 break; 6866 #ifdef WANT_ICEBP 6867 case 0xf1: /* icebp (undocumented, exits to external debugger) */ 6868 gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP); 6869 #if 1 6870 gen_debug(s, pc_start - s->cs_base); 6871 #else 6872 /* start debug */ 6873 tb_flush(cpu_single_env); 6874 qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM); 6875 #endif 6876 break; 6877 #endif 6878 case 0xfa: /* cli */ 6879 if (!s->vm86) { 6880 if (s->cpl <= s->iopl) { 6881 gen_helper_cli(cpu_env); 6882 } else { 6883 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6884 } 6885 } else { 6886 if (s->iopl == 3) { 6887 gen_helper_cli(cpu_env); 6888 } else { 6889 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6890 } 6891 } 6892 break; 6893 case 0xfb: /* sti */ 6894 if (!s->vm86) { 6895 if (s->cpl <= s->iopl) { 6896 gen_sti: 6897 gen_helper_sti(cpu_env); 6898 /* interruptions are enabled only the first insn after sti */ 6899 /* If several instructions disable interrupts, only the 6900 _first_ does it */ 6901 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK)) 6902 gen_helper_set_inhibit_irq(cpu_env); 6903 /* give a chance to handle pending irqs */ 6904 gen_jmp_im(s->pc - s->cs_base); 6905 gen_eob(s); 6906 } else { 6907 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6908 } 6909 } else { 6910 if (s->iopl == 3) { 6911 goto gen_sti; 6912 } else { 6913 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6914 } 6915 } 6916 break; 6917 case 0x62: /* bound */ 6918 if (CODE64(s)) 6919 goto illegal_op; 6920 ot = dflag ? OT_LONG : OT_WORD; 6921 modrm = cpu_ldub_code(cpu_single_env, s->pc++); 6922 reg = (modrm >> 3) & 7; 6923 mod = (modrm >> 6) & 3; 6924 if (mod == 3) 6925 goto illegal_op; 6926 gen_op_mov_TN_reg(ot, 0, reg); 6927 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 6928 gen_jmp_im(pc_start - s->cs_base); 6929 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 6930 if (ot == OT_WORD) { 6931 gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32); 6932 } else { 6933 gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32); 6934 } 6935 break; 6936 case 0x1c8 ... 0x1cf: /* bswap reg */ 6937 reg = (b & 7) | REX_B(s); 6938 #ifdef TARGET_X86_64 6939 if (dflag == 2) { 6940 gen_op_mov_TN_reg(OT_QUAD, 0, reg); 6941 tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]); 6942 gen_op_mov_reg_T0(OT_QUAD, reg); 6943 } else 6944 #endif 6945 { 6946 gen_op_mov_TN_reg(OT_LONG, 0, reg); 6947 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); 6948 tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]); 6949 gen_op_mov_reg_T0(OT_LONG, reg); 6950 } 6951 break; 6952 case 0xd6: /* salc */ 6953 if (CODE64(s)) 6954 goto illegal_op; 6955 gen_compute_eflags_c(s, cpu_T[0], false); 6956 tcg_gen_neg_tl(cpu_T[0], cpu_T[0]); 6957 gen_op_mov_reg_T0(OT_BYTE, R_EAX); 6958 break; 6959 case 0xe0: /* loopnz */ 6960 case 0xe1: /* loopz */ 6961 case 0xe2: /* loop */ 6962 case 0xe3: /* jecxz */ 6963 { 6964 int l1, l2, l3; 6965 6966 tval = (int8_t)insn_get(env, s, OT_BYTE); 6967 next_eip = s->pc - s->cs_base; 6968 tval += next_eip; 6969 if (s->dflag == 0) 6970 tval &= 0xffff; 6971 6972 l1 = gen_new_label(); 6973 l2 = gen_new_label(); 6974 l3 = gen_new_label(); 6975 b &= 3; 6976 switch(b) { 6977 case 0: /* loopnz */ 6978 case 1: /* loopz */ 6979 gen_op_add_reg_im(s->aflag, R_ECX, -1); 6980 gen_op_jz_ecx(s->aflag, l3); 6981 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1); 6982 break; 6983 case 2: /* loop */ 6984 gen_op_add_reg_im(s->aflag, R_ECX, -1); 6985 gen_op_jnz_ecx(s->aflag, l1); 6986 break; 6987 default: 6988 case 3: /* jcxz */ 6989 gen_op_jz_ecx(s->aflag, l1); 6990 break; 6991 } 6992 6993 gen_set_label(l3); 6994 gen_jmp_im(next_eip); 6995 tcg_gen_br(l2); 6996 6997 gen_set_label(l1); 6998 gen_jmp_im(tval); 6999 gen_set_label(l2); 7000 gen_eob(s); 7001 } 7002 break; 7003 case 0x130: /* wrmsr */ 7004 case 0x132: /* rdmsr */ 7005 if (s->cpl != 0) { 7006 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7007 } else { 7008 gen_update_cc_op(s); 7009 gen_jmp_im(pc_start - s->cs_base); 7010 if (b & 2) { 7011 gen_helper_rdmsr(cpu_env); 7012 } else { 7013 gen_helper_wrmsr(cpu_env); 7014 } 7015 } 7016 break; 7017 case 0x131: /* rdtsc */ 7018 gen_update_cc_op(s); 7019 gen_jmp_im(pc_start - s->cs_base); 7020 if (use_icount) 7021 gen_io_start(); 7022 gen_helper_rdtsc(cpu_env); 7023 if (use_icount) { 7024 gen_io_end(); 7025 gen_jmp(s, s->pc - s->cs_base); 7026 } 7027 break; 7028 case 0x133: /* rdpmc */ 7029 gen_update_cc_op(s); 7030 gen_jmp_im(pc_start - s->cs_base); 7031 gen_helper_rdpmc(cpu_env); 7032 break; 7033 case 0x134: /* sysenter */ 7034 /* For Intel SYSENTER is valid on 64-bit */ 7035 if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) 7036 goto illegal_op; 7037 if (!s->pe) { 7038 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7039 } else { 7040 gen_update_cc_op(s); 7041 gen_jmp_im(pc_start - s->cs_base); 7042 gen_helper_sysenter(cpu_env); 7043 gen_eob(s); 7044 } 7045 break; 7046 case 0x135: /* sysexit */ 7047 /* For Intel SYSEXIT is valid on 64-bit */ 7048 if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) 7049 goto illegal_op; 7050 if (!s->pe) { 7051 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7052 } else { 7053 gen_update_cc_op(s); 7054 gen_jmp_im(pc_start - s->cs_base); 7055 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag)); 7056 gen_eob(s); 7057 } 7058 break; 7059 #ifdef TARGET_X86_64 7060 case 0x105: /* syscall */ 7061 /* XXX: is it usable in real mode ? */ 7062 gen_update_cc_op(s); 7063 gen_jmp_im(pc_start - s->cs_base); 7064 gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start)); 7065 gen_eob(s); 7066 break; 7067 case 0x107: /* sysret */ 7068 if (!s->pe) { 7069 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7070 } else { 7071 gen_update_cc_op(s); 7072 gen_jmp_im(pc_start - s->cs_base); 7073 gen_helper_sysret(cpu_env, tcg_const_i32(s->dflag)); 7074 /* condition codes are modified only in long mode */ 7075 if (s->lma) 7076 set_cc_op(s, CC_OP_EFLAGS); 7077 gen_eob(s); 7078 } 7079 break; 7080 #endif 7081 case 0x1a2: /* cpuid */ 7082 gen_update_cc_op(s); 7083 gen_jmp_im(pc_start - s->cs_base); 7084 gen_helper_cpuid(cpu_env); 7085 break; 7086 case 0xf4: /* hlt */ 7087 if (s->cpl != 0) { 7088 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7089 } else { 7090 gen_update_cc_op(s); 7091 gen_jmp_im(pc_start - s->cs_base); 7092 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start)); 7093 s->is_jmp = 3; 7094 } 7095 break; 7096 case 0x100: 7097 modrm = cpu_ldub_code(env, s->pc++); 7098 mod = (modrm >> 6) & 3; 7099 op = (modrm >> 3) & 7; 7100 switch(op) { 7101 case 0: /* sldt */ 7102 if (!s->pe || s->vm86) 7103 goto illegal_op; 7104 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ); 7105 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector)); 7106 ot = OT_WORD; 7107 if (mod == 3) 7108 ot += s->dflag; 7109 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 7110 break; 7111 case 2: /* lldt */ 7112 if (!s->pe || s->vm86) 7113 goto illegal_op; 7114 if (s->cpl != 0) { 7115 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7116 } else { 7117 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE); 7118 gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); 7119 gen_jmp_im(pc_start - s->cs_base); 7120 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 7121 gen_helper_lldt(cpu_env, cpu_tmp2_i32); 7122 } 7123 break; 7124 case 1: /* str */ 7125 if (!s->pe || s->vm86) 7126 goto illegal_op; 7127 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ); 7128 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector)); 7129 ot = OT_WORD; 7130 if (mod == 3) 7131 ot += s->dflag; 7132 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); 7133 break; 7134 case 3: /* ltr */ 7135 if (!s->pe || s->vm86) 7136 goto illegal_op; 7137 if (s->cpl != 0) { 7138 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7139 } else { 7140 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE); 7141 gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); 7142 gen_jmp_im(pc_start - s->cs_base); 7143 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); 7144 gen_helper_ltr(cpu_env, cpu_tmp2_i32); 7145 } 7146 break; 7147 case 4: /* verr */ 7148 case 5: /* verw */ 7149 if (!s->pe || s->vm86) 7150 goto illegal_op; 7151 gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); 7152 gen_update_cc_op(s); 7153 if (op == 4) { 7154 gen_helper_verr(cpu_env, cpu_T[0]); 7155 } else { 7156 gen_helper_verw(cpu_env, cpu_T[0]); 7157 } 7158 set_cc_op(s, CC_OP_EFLAGS); 7159 break; 7160 default: 7161 goto illegal_op; 7162 } 7163 break; 7164 case 0x101: 7165 modrm = cpu_ldub_code(env, s->pc++); 7166 mod = (modrm >> 6) & 3; 7167 op = (modrm >> 3) & 7; 7168 rm = modrm & 7; 7169 switch(op) { 7170 case 0: /* sgdt */ 7171 if (mod == 3) 7172 goto illegal_op; 7173 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ); 7174 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7175 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit)); 7176 gen_op_st_T0_A0(OT_WORD + s->mem_index); 7177 gen_add_A0_im(s, 2); 7178 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base)); 7179 if (!s->dflag) 7180 gen_op_andl_T0_im(0xffffff); 7181 gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index); 7182 break; 7183 case 1: 7184 if (mod == 3) { 7185 switch (rm) { 7186 case 0: /* monitor */ 7187 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || 7188 s->cpl != 0) 7189 goto illegal_op; 7190 gen_update_cc_op(s); 7191 gen_jmp_im(pc_start - s->cs_base); 7192 #ifdef TARGET_X86_64 7193 if (s->aflag == 2) { 7194 gen_op_movq_A0_reg(R_EAX); 7195 } else 7196 #endif 7197 { 7198 gen_op_movl_A0_reg(R_EAX); 7199 if (s->aflag == 0) 7200 gen_op_andl_A0_ffff(); 7201 } 7202 gen_add_A0_ds_seg(s); 7203 gen_helper_monitor(cpu_env, cpu_A0); 7204 break; 7205 case 1: /* mwait */ 7206 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || 7207 s->cpl != 0) 7208 goto illegal_op; 7209 gen_update_cc_op(s); 7210 gen_jmp_im(pc_start - s->cs_base); 7211 gen_helper_mwait(cpu_env, 7212 tcg_const_i32(s->pc - pc_start)); 7213 gen_eob(s); 7214 break; 7215 default: 7216 goto illegal_op; 7217 } 7218 } else { /* sidt */ 7219 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ); 7220 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7221 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit)); 7222 gen_op_st_T0_A0(OT_WORD + s->mem_index); 7223 gen_add_A0_im(s, 2); 7224 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base)); 7225 if (!s->dflag) 7226 gen_op_andl_T0_im(0xffffff); 7227 gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index); 7228 } 7229 break; 7230 case 2: /* lgdt */ 7231 case 3: /* lidt */ 7232 if (mod == 3) { 7233 gen_update_cc_op(s); 7234 gen_jmp_im(pc_start - s->cs_base); 7235 switch(rm) { 7236 case 0: /* VMRUN */ 7237 if (!(s->flags & HF_SVME_MASK) || !s->pe) 7238 goto illegal_op; 7239 if (s->cpl != 0) { 7240 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7241 break; 7242 } else { 7243 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag), 7244 tcg_const_i32(s->pc - pc_start)); 7245 tcg_gen_exit_tb(0); 7246 s->is_jmp = 3; 7247 } 7248 break; 7249 case 1: /* VMMCALL */ 7250 if (!(s->flags & HF_SVME_MASK)) 7251 goto illegal_op; 7252 gen_helper_vmmcall(cpu_env); 7253 break; 7254 case 2: /* VMLOAD */ 7255 if (!(s->flags & HF_SVME_MASK) || !s->pe) 7256 goto illegal_op; 7257 if (s->cpl != 0) { 7258 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7259 break; 7260 } else { 7261 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag)); 7262 } 7263 break; 7264 case 3: /* VMSAVE */ 7265 if (!(s->flags & HF_SVME_MASK) || !s->pe) 7266 goto illegal_op; 7267 if (s->cpl != 0) { 7268 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7269 break; 7270 } else { 7271 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag)); 7272 } 7273 break; 7274 case 4: /* STGI */ 7275 if ((!(s->flags & HF_SVME_MASK) && 7276 !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 7277 !s->pe) 7278 goto illegal_op; 7279 if (s->cpl != 0) { 7280 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7281 break; 7282 } else { 7283 gen_helper_stgi(cpu_env); 7284 } 7285 break; 7286 case 5: /* CLGI */ 7287 if (!(s->flags & HF_SVME_MASK) || !s->pe) 7288 goto illegal_op; 7289 if (s->cpl != 0) { 7290 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7291 break; 7292 } else { 7293 gen_helper_clgi(cpu_env); 7294 } 7295 break; 7296 case 6: /* SKINIT */ 7297 if ((!(s->flags & HF_SVME_MASK) && 7298 !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 7299 !s->pe) 7300 goto illegal_op; 7301 gen_helper_skinit(cpu_env); 7302 break; 7303 case 7: /* INVLPGA */ 7304 if (!(s->flags & HF_SVME_MASK) || !s->pe) 7305 goto illegal_op; 7306 if (s->cpl != 0) { 7307 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7308 break; 7309 } else { 7310 gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag)); 7311 } 7312 break; 7313 default: 7314 goto illegal_op; 7315 } 7316 } else if (s->cpl != 0) { 7317 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7318 } else { 7319 gen_svm_check_intercept(s, pc_start, 7320 op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE); 7321 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7322 gen_op_ld_T1_A0(OT_WORD + s->mem_index); 7323 gen_add_A0_im(s, 2); 7324 gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index); 7325 if (!s->dflag) 7326 gen_op_andl_T0_im(0xffffff); 7327 if (op == 2) { 7328 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base)); 7329 tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit)); 7330 } else { 7331 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base)); 7332 tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit)); 7333 } 7334 } 7335 break; 7336 case 4: /* smsw */ 7337 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0); 7338 #if defined TARGET_X86_64 && defined WORDS_BIGENDIAN 7339 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4); 7340 #else 7341 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0])); 7342 #endif 7343 gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 1); 7344 break; 7345 case 6: /* lmsw */ 7346 if (s->cpl != 0) { 7347 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7348 } else { 7349 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0); 7350 gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); 7351 gen_helper_lmsw(cpu_env, cpu_T[0]); 7352 gen_jmp_im(s->pc - s->cs_base); 7353 gen_eob(s); 7354 } 7355 break; 7356 case 7: /* invlpg */ 7357 if (s->cpl != 0) { 7358 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7359 } else { 7360 if (mod == 3) { 7361 #ifdef TARGET_X86_64 7362 if (CODE64(s) && rm == 0) { 7363 /* swapgs */ 7364 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[R_GS].base)); 7365 tcg_gen_ld_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,kernelgsbase)); 7366 tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,segs[R_GS].base)); 7367 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,kernelgsbase)); 7368 } else 7369 #endif 7370 { 7371 goto illegal_op; 7372 } 7373 } else { 7374 gen_update_cc_op(s); 7375 gen_jmp_im(pc_start - s->cs_base); 7376 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7377 gen_helper_invlpg(cpu_env, cpu_A0); 7378 gen_jmp_im(s->pc - s->cs_base); 7379 gen_eob(s); 7380 } 7381 } 7382 break; 7383 default: 7384 goto illegal_op; 7385 } 7386 break; 7387 case 0x108: /* invd */ 7388 case 0x109: /* wbinvd */ 7389 if (s->cpl != 0) { 7390 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7391 } else { 7392 gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD); 7393 /* nothing to do */ 7394 } 7395 break; 7396 case 0x63: /* arpl or movslS (x86_64) */ 7397 #ifdef TARGET_X86_64 7398 if (CODE64(s)) { 7399 int d_ot; 7400 /* d_ot is the size of destination */ 7401 d_ot = dflag + OT_WORD; 7402 7403 modrm = cpu_ldub_code(env, s->pc++); 7404 reg = ((modrm >> 3) & 7) | rex_r; 7405 mod = (modrm >> 6) & 3; 7406 rm = (modrm & 7) | REX_B(s); 7407 7408 if (mod == 3) { 7409 gen_op_mov_TN_reg(OT_LONG, 0, rm); 7410 /* sign extend */ 7411 if (d_ot == OT_QUAD) 7412 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); 7413 gen_op_mov_reg_T0(d_ot, reg); 7414 } else { 7415 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7416 if (d_ot == OT_QUAD) { 7417 gen_op_lds_T0_A0(OT_LONG + s->mem_index); 7418 } else { 7419 gen_op_ld_T0_A0(OT_LONG + s->mem_index); 7420 } 7421 gen_op_mov_reg_T0(d_ot, reg); 7422 } 7423 } else 7424 #endif 7425 { 7426 int label1; 7427 TCGv t0, t1, t2; 7428 7429 if (!s->pe || s->vm86) 7430 goto illegal_op; 7431 t0 = tcg_temp_local_new(); 7432 t1 = tcg_temp_local_new(); 7433 t2 = tcg_temp_local_new(); 7434 ot = OT_WORD; 7435 modrm = cpu_ldub_code(env, s->pc++); 7436 reg = (modrm >> 3) & 7; 7437 mod = (modrm >> 6) & 3; 7438 rm = modrm & 7; 7439 if (mod != 3) { 7440 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7441 gen_op_ld_v(ot + s->mem_index, t0, cpu_A0); 7442 } else { 7443 gen_op_mov_v_reg(ot, t0, rm); 7444 } 7445 gen_op_mov_v_reg(ot, t1, reg); 7446 tcg_gen_andi_tl(cpu_tmp0, t0, 3); 7447 tcg_gen_andi_tl(t1, t1, 3); 7448 tcg_gen_movi_tl(t2, 0); 7449 label1 = gen_new_label(); 7450 tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1); 7451 tcg_gen_andi_tl(t0, t0, ~3); 7452 tcg_gen_or_tl(t0, t0, t1); 7453 tcg_gen_movi_tl(t2, CC_Z); 7454 gen_set_label(label1); 7455 if (mod != 3) { 7456 gen_op_st_v(ot + s->mem_index, t0, cpu_A0); 7457 } else { 7458 gen_op_mov_reg_v(ot, rm, t0); 7459 } 7460 gen_compute_eflags(s); 7461 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z); 7462 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2); 7463 tcg_temp_free(t0); 7464 tcg_temp_free(t1); 7465 tcg_temp_free(t2); 7466 } 7467 break; 7468 case 0x102: /* lar */ 7469 case 0x103: /* lsl */ 7470 { 7471 int label1; 7472 TCGv t0; 7473 if (!s->pe || s->vm86) 7474 goto illegal_op; 7475 ot = dflag ? OT_LONG : OT_WORD; 7476 modrm = cpu_ldub_code(env, s->pc++); 7477 reg = ((modrm >> 3) & 7) | rex_r; 7478 gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); 7479 t0 = tcg_temp_local_new(); 7480 gen_update_cc_op(s); 7481 if (b == 0x102) { 7482 gen_helper_lar(t0, cpu_env, cpu_T[0]); 7483 } else { 7484 gen_helper_lsl(t0, cpu_env, cpu_T[0]); 7485 } 7486 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z); 7487 label1 = gen_new_label(); 7488 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1); 7489 gen_op_mov_reg_v(ot, reg, t0); 7490 gen_set_label(label1); 7491 set_cc_op(s, CC_OP_EFLAGS); 7492 tcg_temp_free(t0); 7493 } 7494 break; 7495 case 0x118: 7496 modrm = cpu_ldub_code(env, s->pc++); 7497 mod = (modrm >> 6) & 3; 7498 op = (modrm >> 3) & 7; 7499 switch(op) { 7500 case 0: /* prefetchnta */ 7501 case 1: /* prefetchnt0 */ 7502 case 2: /* prefetchnt0 */ 7503 case 3: /* prefetchnt0 */ 7504 if (mod == 3) 7505 goto illegal_op; 7506 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7507 /* nothing more to do */ 7508 break; 7509 default: /* nop (multi byte) */ 7510 gen_nop_modrm(env, s, modrm); 7511 break; 7512 } 7513 break; 7514 case 0x119 ... 0x11f: /* nop (multi byte) */ 7515 modrm = cpu_ldub_code(env, s->pc++); 7516 gen_nop_modrm(env, s, modrm); 7517 break; 7518 case 0x120: /* mov reg, crN */ 7519 case 0x122: /* mov crN, reg */ 7520 if (s->cpl != 0) { 7521 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7522 } else { 7523 modrm = cpu_ldub_code(env, s->pc++); 7524 if ((modrm & 0xc0) != 0xc0) 7525 goto illegal_op; 7526 rm = (modrm & 7) | REX_B(s); 7527 reg = ((modrm >> 3) & 7) | rex_r; 7528 if (CODE64(s)) 7529 ot = OT_QUAD; 7530 else 7531 ot = OT_LONG; 7532 switch(reg) { 7533 case 0: 7534 case 2: 7535 case 3: 7536 case 4: 7537 case 8: 7538 gen_update_cc_op(s); 7539 gen_jmp_im(pc_start - s->cs_base); 7540 if (b & 2) { 7541 gen_op_mov_TN_reg(ot, 0, rm); 7542 gen_helper_write_crN(cpu_env, tcg_const_i32(reg), cpu_T[0]); 7543 gen_jmp_im(s->pc - s->cs_base); 7544 gen_eob(s); 7545 } else { 7546 gen_helper_read_crN(cpu_T[0], cpu_env, tcg_const_i32(reg)); 7547 gen_op_mov_reg_T0(ot, rm); 7548 } 7549 break; 7550 default: 7551 goto illegal_op; 7552 } 7553 } 7554 break; 7555 case 0x121: /* mov reg, drN */ 7556 case 0x123: /* mov drN, reg */ 7557 if (s->cpl != 0) { 7558 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7559 } else { 7560 modrm = cpu_ldub_code(env, s->pc++); 7561 if ((modrm & 0xc0) != 0xc0) 7562 goto illegal_op; 7563 rm = (modrm & 7) | REX_B(s); 7564 reg = ((modrm >> 3) & 7) | rex_r; 7565 if (CODE64(s)) 7566 ot = OT_QUAD; 7567 else 7568 ot = OT_LONG; 7569 /* XXX: do it dynamically with CR4.DE bit */ 7570 if (reg == 4 || reg == 5 || reg >= 8) 7571 goto illegal_op; 7572 if (b & 2) { 7573 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg); 7574 gen_op_mov_TN_reg(ot, 0, rm); 7575 gen_helper_movl_drN_T0(cpu_env, tcg_const_i32(reg), cpu_T[0]); 7576 gen_jmp_im(s->pc - s->cs_base); 7577 gen_eob(s); 7578 } else { 7579 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg); 7580 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg])); 7581 gen_op_mov_reg_T0(ot, rm); 7582 } 7583 } 7584 break; 7585 case 0x106: /* clts */ 7586 if (s->cpl != 0) { 7587 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 7588 } else { 7589 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0); 7590 gen_helper_clts(cpu_env); 7591 /* abort block because static cpu state changed */ 7592 gen_jmp_im(s->pc - s->cs_base); 7593 gen_eob(s); 7594 } 7595 break; 7596 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */ 7597 case 0x1c3: /* MOVNTI reg, mem */ 7598 if (!(s->cpuid_features & CPUID_SSE2)) 7599 goto illegal_op; 7600 ot = s->dflag == 2 ? OT_QUAD : OT_LONG; 7601 modrm = cpu_ldub_code(env, s->pc++); 7602 mod = (modrm >> 6) & 3; 7603 if (mod == 3) 7604 goto illegal_op; 7605 reg = ((modrm >> 3) & 7) | rex_r; 7606 /* generate a generic store */ 7607 gen_ldst_modrm(env, s, modrm, ot, reg, 1); 7608 break; 7609 case 0x1ae: 7610 modrm = cpu_ldub_code(env, s->pc++); 7611 mod = (modrm >> 6) & 3; 7612 op = (modrm >> 3) & 7; 7613 switch(op) { 7614 case 0: /* fxsave */ 7615 if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || 7616 (s->flags & HF_EM_MASK)) 7617 goto illegal_op; 7618 if (s->flags & HF_TS_MASK) { 7619 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); 7620 break; 7621 } 7622 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7623 gen_update_cc_op(s); 7624 gen_jmp_im(pc_start - s->cs_base); 7625 gen_helper_fxsave(cpu_env, cpu_A0, tcg_const_i32((s->dflag == 2))); 7626 break; 7627 case 1: /* fxrstor */ 7628 if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || 7629 (s->flags & HF_EM_MASK)) 7630 goto illegal_op; 7631 if (s->flags & HF_TS_MASK) { 7632 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); 7633 break; 7634 } 7635 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7636 gen_update_cc_op(s); 7637 gen_jmp_im(pc_start - s->cs_base); 7638 gen_helper_fxrstor(cpu_env, cpu_A0, tcg_const_i32((s->dflag == 2))); 7639 break; 7640 case 2: /* ldmxcsr */ 7641 case 3: /* stmxcsr */ 7642 if (s->flags & HF_TS_MASK) { 7643 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); 7644 break; 7645 } 7646 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) || 7647 mod == 3) 7648 goto illegal_op; 7649 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7650 if (op == 2) { 7651 gen_op_ld_T0_A0(OT_LONG + s->mem_index); 7652 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr)); 7653 } else { 7654 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr)); 7655 gen_op_st_T0_A0(OT_LONG + s->mem_index); 7656 } 7657 break; 7658 case 5: /* lfence */ 7659 case 6: /* mfence */ 7660 if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE)) 7661 goto illegal_op; 7662 break; 7663 case 7: /* sfence / clflush */ 7664 if ((modrm & 0xc7) == 0xc0) { 7665 /* sfence */ 7666 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */ 7667 if (!(s->cpuid_features & CPUID_SSE)) 7668 goto illegal_op; 7669 } else { 7670 /* clflush */ 7671 if (!(s->cpuid_features & CPUID_CLFLUSH)) 7672 goto illegal_op; 7673 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7674 } 7675 break; 7676 default: 7677 goto illegal_op; 7678 } 7679 break; 7680 case 0x10d: /* 3DNow! prefetch(w) */ 7681 modrm = cpu_ldub_code(env, s->pc++); 7682 mod = (modrm >> 6) & 3; 7683 if (mod == 3) 7684 goto illegal_op; 7685 gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); 7686 /* ignore for now */ 7687 break; 7688 case 0x1aa: /* rsm */ 7689 gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM); 7690 if (!(s->flags & HF_SMM_MASK)) 7691 goto illegal_op; 7692 gen_update_cc_op(s); 7693 gen_jmp_im(s->pc - s->cs_base); 7694 gen_helper_rsm(cpu_env); 7695 gen_eob(s); 7696 break; 7697 case 0x1b8: /* SSE4.2 popcnt */ 7698 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) != 7699 PREFIX_REPZ) 7700 goto illegal_op; 7701 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT)) 7702 goto illegal_op; 7703 7704 modrm = cpu_ldub_code(env, s->pc++); 7705 reg = ((modrm >> 3) & 7); 7706 7707 if (s->prefix & PREFIX_DATA) 7708 ot = OT_WORD; 7709 else if (s->dflag != 2) 7710 ot = OT_LONG; 7711 else 7712 ot = OT_QUAD; 7713 7714 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); 7715 gen_helper_popcnt(cpu_T[0], cpu_env, cpu_T[0], tcg_const_i32(ot)); 7716 gen_op_mov_reg_T0(ot, reg); 7717 7718 set_cc_op(s, CC_OP_EFLAGS); 7719 break; 7720 case 0x10e ... 0x10f: 7721 /* 3DNow! instructions, ignore prefixes */ 7722 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA); 7723 case 0x110 ... 0x117: 7724 case 0x128 ... 0x12f: 7725 case 0x138 ... 0x13a: 7726 case 0x150 ... 0x177: 7727 case 0x17c ... 0x17f: 7728 case 0x1c2: 7729 case 0x1c4 ... 0x1c6: 7730 case 0x1d0 ... 0x1fe: 7731 gen_sse(env, s, b, pc_start, rex_r); 7732 break; 7733 default: 7734 goto illegal_op; 7735 } 7736 /* lock generation */ 7737 if (s->prefix & PREFIX_LOCK) 7738 gen_helper_unlock(); 7739 return s->pc; 7740 illegal_op: 7741 if (s->prefix & PREFIX_LOCK) 7742 gen_helper_unlock(); 7743 /* XXX: ensure that no lock was generated */ 7744 gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base); 7745 return s->pc; 7746 } 7747 7748 void optimize_flags_init(void) 7749 { 7750 #if TCG_TARGET_REG_BITS == 32 7751 assert(sizeof(CCTable) == (1 << 3)); 7752 #else 7753 assert(sizeof(CCTable) == (1 << 4)); 7754 #endif 7755 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); 7756 cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0, 7757 offsetof(CPUX86State, cc_op), "cc_op"); 7758 cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src), 7759 "cc_src"); 7760 cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst), 7761 "cc_dst"); 7762 } 7763 7764 /* generate intermediate code in tcg_ctx.gen_opc_buf and gen_opparam_buf for 7765 basic block 'tb'. If search_pc is TRUE, also generate PC 7766 information for each intermediate instruction. */ 7767 static inline void gen_intermediate_code_internal(CPUX86State *env, 7768 TranslationBlock *tb, 7769 int search_pc) 7770 { 7771 DisasContext dc1, *dc = &dc1; 7772 target_ulong pc_ptr; 7773 uint16_t *gen_opc_end; 7774 CPUBreakpoint *bp; 7775 int j, lj; 7776 uint64_t flags; 7777 target_ulong pc_start; 7778 target_ulong cs_base; 7779 int num_insns; 7780 int max_insns; 7781 7782 /* generate intermediate code */ 7783 pc_start = tb->pc; 7784 cs_base = tb->cs_base; 7785 flags = tb->flags; 7786 7787 dc->pe = (flags >> HF_PE_SHIFT) & 1; 7788 dc->code32 = (flags >> HF_CS32_SHIFT) & 1; 7789 dc->ss32 = (flags >> HF_SS32_SHIFT) & 1; 7790 dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1; 7791 dc->f_st = 0; 7792 dc->vm86 = (flags >> VM_SHIFT) & 1; 7793 dc->cpl = (flags >> HF_CPL_SHIFT) & 3; 7794 dc->iopl = (flags >> IOPL_SHIFT) & 3; 7795 dc->tf = (flags >> TF_SHIFT) & 1; 7796 dc->singlestep_enabled = ENV_GET_CPU(env)->singlestep_enabled; 7797 dc->cc_op = CC_OP_DYNAMIC; 7798 dc->cc_op_dirty = false; 7799 dc->cs_base = cs_base; 7800 dc->tb = tb; 7801 dc->popl_esp_hack = 0; 7802 /* select memory access functions */ 7803 dc->mem_index = 0; 7804 if (flags & HF_SOFTMMU_MASK) { 7805 if (dc->cpl == 3) 7806 dc->mem_index = 2 * 4; 7807 else 7808 dc->mem_index = 1 * 4; 7809 } 7810 dc->cpuid_features = env->cpuid_features; 7811 dc->cpuid_ext_features = env->cpuid_ext_features; 7812 dc->cpuid_ext2_features = env->cpuid_ext2_features; 7813 dc->cpuid_ext3_features = env->cpuid_ext3_features; 7814 #ifdef TARGET_X86_64 7815 dc->lma = (flags >> HF_LMA_SHIFT) & 1; 7816 dc->code64 = (flags >> HF_CS64_SHIFT) & 1; 7817 #endif 7818 dc->flags = flags; 7819 dc->jmp_opt = !(dc->tf || ENV_GET_CPU(env)->singlestep_enabled || 7820 (flags & HF_INHIBIT_IRQ_MASK) 7821 #ifndef CONFIG_SOFTMMU 7822 || (flags & HF_SOFTMMU_MASK) 7823 #endif 7824 ); 7825 #if 0 7826 /* check addseg logic */ 7827 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32)) 7828 printf("ERROR addseg\n"); 7829 #endif 7830 7831 cpu_T[0] = tcg_temp_new(); 7832 cpu_T[1] = tcg_temp_new(); 7833 cpu_A0 = tcg_temp_new(); 7834 cpu_T3 = tcg_temp_new(); 7835 7836 cpu_tmp0 = tcg_temp_new(); 7837 cpu_tmp1_i64 = tcg_temp_new_i64(); 7838 cpu_tmp2_i32 = tcg_temp_new_i32(); 7839 cpu_tmp3_i32 = tcg_temp_new_i32(); 7840 cpu_tmp4 = tcg_temp_new(); 7841 cpu_tmp5 = tcg_temp_new(); 7842 cpu_tmp6 = tcg_temp_new(); 7843 cpu_ptr0 = tcg_temp_new_ptr(); 7844 cpu_ptr1 = tcg_temp_new_ptr(); 7845 7846 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; 7847 7848 dc->is_jmp = DISAS_NEXT; 7849 pc_ptr = pc_start; 7850 lj = -1; 7851 num_insns = 0; 7852 max_insns = tb->cflags & CF_COUNT_MASK; 7853 if (max_insns == 0) 7854 max_insns = CF_COUNT_MASK; 7855 7856 gen_icount_start(); 7857 for(;;) { 7858 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { 7859 QTAILQ_FOREACH(bp, &env->breakpoints, entry) { 7860 if (bp->pc == pc_ptr && 7861 !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) { 7862 gen_debug(dc, pc_ptr - dc->cs_base); 7863 break; 7864 } 7865 } 7866 } 7867 if (search_pc) { 7868 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; 7869 if (lj < j) { 7870 lj++; 7871 while (lj < j) 7872 tcg_ctx.gen_opc_instr_start[lj++] = 0; 7873 } 7874 tcg_ctx.gen_opc_pc[lj] = pc_ptr; 7875 gen_opc_cc_op[lj] = dc->cc_op; 7876 tcg_ctx.gen_opc_instr_start[lj] = 1; 7877 tcg_ctx.gen_opc_icount[lj] = num_insns; 7878 } 7879 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) 7880 gen_io_start(); 7881 7882 pc_ptr = disas_insn(env, dc, pc_ptr); 7883 num_insns++; 7884 #ifdef CONFIG_HAX 7885 if (hax_enabled() && hax_stop_translate(ENV_GET_CPU(env))) 7886 { 7887 gen_jmp_im(pc_ptr - dc->cs_base); 7888 gen_eob(dc); 7889 break; 7890 } 7891 #endif 7892 /* stop translation if indicated */ 7893 if (dc->is_jmp) 7894 break; 7895 /* if single step mode, we generate only one instruction and 7896 generate an exception */ 7897 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear 7898 the flag and abort the translation to give the irqs a 7899 change to be happen */ 7900 if (dc->tf || dc->singlestep_enabled || 7901 (flags & HF_INHIBIT_IRQ_MASK)) { 7902 gen_jmp_im(pc_ptr - dc->cs_base); 7903 gen_eob(dc); 7904 break; 7905 } 7906 /* if too long translation, stop generation too */ 7907 if (tcg_ctx.gen_opc_ptr >= gen_opc_end || 7908 (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) || 7909 num_insns >= max_insns) { 7910 gen_jmp_im(pc_ptr - dc->cs_base); 7911 gen_eob(dc); 7912 break; 7913 } 7914 if (singlestep) { 7915 gen_jmp_im(pc_ptr - dc->cs_base); 7916 gen_eob(dc); 7917 break; 7918 } 7919 } 7920 if (tb->cflags & CF_LAST_IO) 7921 gen_io_end(); 7922 gen_icount_end(tb, num_insns); 7923 *tcg_ctx.gen_opc_ptr = INDEX_op_end; 7924 /* we don't forget to fill the last values */ 7925 if (search_pc) { 7926 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; 7927 lj++; 7928 while (lj <= j) 7929 tcg_ctx.gen_opc_instr_start[lj++] = 0; 7930 } 7931 7932 #ifdef DEBUG_DISAS 7933 log_cpu_state_mask(CPU_LOG_TB_CPU, ENV_GET_CPU(env), X86_DUMP_CCOP); 7934 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { 7935 int disas_flags; 7936 qemu_log("----------------\n"); 7937 qemu_log("IN: %s\n", lookup_symbol(pc_start)); 7938 #ifdef TARGET_X86_64 7939 if (dc->code64) 7940 disas_flags = 2; 7941 else 7942 #endif 7943 disas_flags = !dc->code32; 7944 log_target_disas(env, pc_start, pc_ptr - pc_start, disas_flags); 7945 qemu_log("\n"); 7946 } 7947 #endif 7948 7949 if (!search_pc) { 7950 tb->size = pc_ptr - pc_start; 7951 tb->icount = num_insns; 7952 } 7953 } 7954 7955 void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb) 7956 { 7957 gen_intermediate_code_internal(env, tb, 0); 7958 } 7959 7960 void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb) 7961 { 7962 gen_intermediate_code_internal(env, tb, 1); 7963 } 7964 7965 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos) 7966 { 7967 int cc_op; 7968 #ifdef DEBUG_DISAS 7969 if (qemu_loglevel_mask(CPU_LOG_TB_OP)) { 7970 int i; 7971 qemu_log("RESTORE:\n"); 7972 for(i = 0;i <= pc_pos; i++) { 7973 if (tcg_ctx.gen_opc_instr_start[i]) { 7974 qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, 7975 tcg_ctx.gen_opc_pc[i]); 7976 } 7977 } 7978 qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n", 7979 pc_pos, tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base, 7980 (uint32_t)tb->cs_base); 7981 } 7982 #endif 7983 env->eip = tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base; 7984 cc_op = gen_opc_cc_op[pc_pos]; 7985 if (cc_op != CC_OP_DYNAMIC) 7986 env->cc_op = cc_op; 7987 } 7988