60 |
60 |
/* global register indexes */
|
61 |
61 |
static TCGv cpu_env, cpu_T[2], cpu_A0;
|
62 |
62 |
/* local register indexes (only used inside old micro ops) */
|
63 |
|
static TCGv cpu_tmp0;
|
|
63 |
static TCGv cpu_tmp0, cpu_tmp1;
|
64 |
64 |
|
65 |
65 |
#ifdef TARGET_X86_64
|
66 |
66 |
static int x86_64_hregs;
|
... | ... | |
2376 |
2376 |
gen_jmp_tb(s, eip, 0);
|
2377 |
2377 |
}
|
2378 |
2378 |
|
2379 |
|
static GenOpFunc1 *gen_ldq_env_A0[3] = {
|
2380 |
|
gen_op_ldq_raw_env_A0,
|
2381 |
|
#ifndef CONFIG_USER_ONLY
|
2382 |
|
gen_op_ldq_kernel_env_A0,
|
2383 |
|
gen_op_ldq_user_env_A0,
|
2384 |
|
#endif
|
2385 |
|
};
|
|
2379 |
static inline void gen_ldq_env_A0(int idx, int offset)
|
|
2380 |
{
|
|
2381 |
int mem_index = (idx >> 2) - 1;
|
|
2382 |
tcg_gen_qemu_ld64(cpu_tmp1, cpu_A0, mem_index);
|
|
2383 |
tcg_gen_st_i64(cpu_tmp1, cpu_env, offset);
|
|
2384 |
}
|
2386 |
2385 |
|
2387 |
|
static GenOpFunc1 *gen_stq_env_A0[3] = {
|
2388 |
|
gen_op_stq_raw_env_A0,
|
2389 |
|
#ifndef CONFIG_USER_ONLY
|
2390 |
|
gen_op_stq_kernel_env_A0,
|
2391 |
|
gen_op_stq_user_env_A0,
|
2392 |
|
#endif
|
2393 |
|
};
|
|
2386 |
static inline void gen_stq_env_A0(int idx, int offset)
|
|
2387 |
{
|
|
2388 |
int mem_index = (idx >> 2) - 1;
|
|
2389 |
tcg_gen_ld_i64(cpu_tmp1, cpu_env, offset);
|
|
2390 |
tcg_gen_qemu_st64(cpu_tmp1, cpu_A0, mem_index);
|
|
2391 |
}
|
2394 |
2392 |
|
2395 |
|
static GenOpFunc1 *gen_ldo_env_A0[3] = {
|
2396 |
|
gen_op_ldo_raw_env_A0,
|
2397 |
|
#ifndef CONFIG_USER_ONLY
|
2398 |
|
gen_op_ldo_kernel_env_A0,
|
2399 |
|
gen_op_ldo_user_env_A0,
|
2400 |
|
#endif
|
2401 |
|
};
|
|
2393 |
static inline void gen_ldo_env_A0(int idx, int offset)
|
|
2394 |
{
|
|
2395 |
int mem_index = (idx >> 2) - 1;
|
|
2396 |
tcg_gen_qemu_ld64(cpu_tmp1, cpu_A0, mem_index);
|
|
2397 |
tcg_gen_st_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
|
|
2398 |
tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
|
|
2399 |
tcg_gen_qemu_ld64(cpu_tmp1, cpu_tmp0, mem_index);
|
|
2400 |
tcg_gen_st_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
|
|
2401 |
}
|
2402 |
2402 |
|
2403 |
|
static GenOpFunc1 *gen_sto_env_A0[3] = {
|
2404 |
|
gen_op_sto_raw_env_A0,
|
2405 |
|
#ifndef CONFIG_USER_ONLY
|
2406 |
|
gen_op_sto_kernel_env_A0,
|
2407 |
|
gen_op_sto_user_env_A0,
|
2408 |
|
#endif
|
2409 |
|
};
|
|
2403 |
static inline void gen_sto_env_A0(int idx, int offset)
|
|
2404 |
{
|
|
2405 |
int mem_index = (idx >> 2) - 1;
|
|
2406 |
tcg_gen_ld_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
|
|
2407 |
tcg_gen_qemu_st64(cpu_tmp1, cpu_A0, mem_index);
|
|
2408 |
tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
|
|
2409 |
tcg_gen_ld_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
|
|
2410 |
tcg_gen_qemu_st64(cpu_tmp1, cpu_tmp0, mem_index);
|
|
2411 |
}
|
2410 |
2412 |
|
2411 |
2413 |
#define SSE_SPECIAL ((GenOpFunc2 *)1)
|
2412 |
2414 |
#define SSE_DUMMY ((GenOpFunc2 *)2)
|
... | ... | |
2680 |
2682 |
if (mod == 3)
|
2681 |
2683 |
goto illegal_op;
|
2682 |
2684 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2683 |
|
gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
|
|
2685 |
gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
|
2684 |
2686 |
break;
|
2685 |
2687 |
case 0x1e7: /* movntdq */
|
2686 |
2688 |
case 0x02b: /* movntps */
|
... | ... | |
2689 |
2691 |
if (mod == 3)
|
2690 |
2692 |
goto illegal_op;
|
2691 |
2693 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2692 |
|
gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
|
|
2694 |
gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
|
2693 |
2695 |
break;
|
2694 |
2696 |
case 0x6e: /* movd mm, ea */
|
2695 |
2697 |
#ifdef TARGET_X86_64
|
... | ... | |
2718 |
2720 |
case 0x6f: /* movq mm, ea */
|
2719 |
2721 |
if (mod != 3) {
|
2720 |
2722 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2721 |
|
gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
|
|
2723 |
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
|
2722 |
2724 |
} else {
|
2723 |
2725 |
rm = (modrm & 7);
|
2724 |
2726 |
gen_op_movq(offsetof(CPUX86State,fpregs[reg].mmx),
|
... | ... | |
2733 |
2735 |
case 0x26f: /* movdqu xmm, ea */
|
2734 |
2736 |
if (mod != 3) {
|
2735 |
2737 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2736 |
|
gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
|
|
2738 |
gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
|
2737 |
2739 |
} else {
|
2738 |
2740 |
rm = (modrm & 7) | REX_B(s);
|
2739 |
2741 |
gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
|
... | ... | |
2758 |
2760 |
case 0x310: /* movsd xmm, ea */
|
2759 |
2761 |
if (mod != 3) {
|
2760 |
2762 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2761 |
|
gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
|
2763 |
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
2762 |
2764 |
gen_op_movl_T0_0();
|
2763 |
2765 |
gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
|
2764 |
2766 |
gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
|
... | ... | |
2772 |
2774 |
case 0x112: /* movlpd */
|
2773 |
2775 |
if (mod != 3) {
|
2774 |
2776 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2775 |
|
gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
|
2777 |
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
2776 |
2778 |
} else {
|
2777 |
2779 |
/* movhlps */
|
2778 |
2780 |
rm = (modrm & 7) | REX_B(s);
|
... | ... | |
2783 |
2785 |
case 0x212: /* movsldup */
|
2784 |
2786 |
if (mod != 3) {
|
2785 |
2787 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2786 |
|
gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
|
|
2788 |
gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
|
2787 |
2789 |
} else {
|
2788 |
2790 |
rm = (modrm & 7) | REX_B(s);
|
2789 |
2791 |
gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
|
... | ... | |
2799 |
2801 |
case 0x312: /* movddup */
|
2800 |
2802 |
if (mod != 3) {
|
2801 |
2803 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2802 |
|
gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
|
2804 |
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
2803 |
2805 |
} else {
|
2804 |
2806 |
rm = (modrm & 7) | REX_B(s);
|
2805 |
2807 |
gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
|
... | ... | |
2812 |
2814 |
case 0x116: /* movhpd */
|
2813 |
2815 |
if (mod != 3) {
|
2814 |
2816 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2815 |
|
gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
|
|
2817 |
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
|
2816 |
2818 |
} else {
|
2817 |
2819 |
/* movlhps */
|
2818 |
2820 |
rm = (modrm & 7) | REX_B(s);
|
... | ... | |
2823 |
2825 |
case 0x216: /* movshdup */
|
2824 |
2826 |
if (mod != 3) {
|
2825 |
2827 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2826 |
|
gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
|
|
2828 |
gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
|
2827 |
2829 |
} else {
|
2828 |
2830 |
rm = (modrm & 7) | REX_B(s);
|
2829 |
2831 |
gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
|
... | ... | |
2863 |
2865 |
case 0x27e: /* movq xmm, ea */
|
2864 |
2866 |
if (mod != 3) {
|
2865 |
2867 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2866 |
|
gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
|
2868 |
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
2867 |
2869 |
} else {
|
2868 |
2870 |
rm = (modrm & 7) | REX_B(s);
|
2869 |
2871 |
gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
|
... | ... | |
2874 |
2876 |
case 0x7f: /* movq ea, mm */
|
2875 |
2877 |
if (mod != 3) {
|
2876 |
2878 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2877 |
|
gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
|
|
2879 |
gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
|
2878 |
2880 |
} else {
|
2879 |
2881 |
rm = (modrm & 7);
|
2880 |
2882 |
gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
|
... | ... | |
2889 |
2891 |
case 0x27f: /* movdqu ea, xmm */
|
2890 |
2892 |
if (mod != 3) {
|
2891 |
2893 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2892 |
|
gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
|
|
2894 |
gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
|
2893 |
2895 |
} else {
|
2894 |
2896 |
rm = (modrm & 7) | REX_B(s);
|
2895 |
2897 |
gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
|
... | ... | |
2910 |
2912 |
case 0x311: /* movsd ea, xmm */
|
2911 |
2913 |
if (mod != 3) {
|
2912 |
2914 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2913 |
|
gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
|
2915 |
gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
2914 |
2916 |
} else {
|
2915 |
2917 |
rm = (modrm & 7) | REX_B(s);
|
2916 |
2918 |
gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
|
... | ... | |
2921 |
2923 |
case 0x113: /* movlpd */
|
2922 |
2924 |
if (mod != 3) {
|
2923 |
2925 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2924 |
|
gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
|
2926 |
gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
2925 |
2927 |
} else {
|
2926 |
2928 |
goto illegal_op;
|
2927 |
2929 |
}
|
... | ... | |
2930 |
2932 |
case 0x117: /* movhpd */
|
2931 |
2933 |
if (mod != 3) {
|
2932 |
2934 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2933 |
|
gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
|
|
2935 |
gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
|
2934 |
2936 |
} else {
|
2935 |
2937 |
goto illegal_op;
|
2936 |
2938 |
}
|
... | ... | |
2983 |
2985 |
if (mod != 3) {
|
2984 |
2986 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
2985 |
2987 |
op2_offset = offsetof(CPUX86State,mmx_t0);
|
2986 |
|
gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
|
|
2988 |
gen_ldq_env_A0(s->mem_index, op2_offset);
|
2987 |
2989 |
} else {
|
2988 |
2990 |
rm = (modrm & 7);
|
2989 |
2991 |
op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
|
... | ... | |
3014 |
3016 |
if (mod != 3) {
|
3015 |
3017 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
3016 |
3018 |
op2_offset = offsetof(CPUX86State,xmm_t0);
|
3017 |
|
gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
|
|
3019 |
gen_ldo_env_A0(s->mem_index, op2_offset);
|
3018 |
3020 |
} else {
|
3019 |
3021 |
rm = (modrm & 7) | REX_B(s);
|
3020 |
3022 |
op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
|
... | ... | |
3043 |
3045 |
if (mod != 3) {
|
3044 |
3046 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
3045 |
3047 |
if ((b >> 8) & 1) {
|
3046 |
|
gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
|
|
3048 |
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
|
3047 |
3049 |
} else {
|
3048 |
3050 |
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
|
3049 |
3051 |
gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
|
... | ... | |
3090 |
3092 |
case 0x1d6: /* movq ea, xmm */
|
3091 |
3093 |
if (mod != 3) {
|
3092 |
3094 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
3093 |
|
gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
|
3095 |
gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
|
3094 |
3096 |
} else {
|
3095 |
3097 |
rm = (modrm & 7) | REX_B(s);
|
3096 |
3098 |
gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
|
... | ... | |
3169 |
3171 |
gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
|
3170 |
3172 |
} else {
|
3171 |
3173 |
/* 64 bit access */
|
3172 |
|
gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_D(0)));
|
|
3174 |
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
|
3173 |
3175 |
}
|
3174 |
3176 |
} else {
|
3175 |
|
gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
|
|
3177 |
gen_ldo_env_A0(s->mem_index, op2_offset);
|
3176 |
3178 |
}
|
3177 |
3179 |
} else {
|
3178 |
3180 |
rm = (modrm & 7) | REX_B(s);
|
... | ... | |
3183 |
3185 |
if (mod != 3) {
|
3184 |
3186 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
3185 |
3187 |
op2_offset = offsetof(CPUX86State,mmx_t0);
|
3186 |
|
gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
|
|
3188 |
gen_ldq_env_A0(s->mem_index, op2_offset);
|
3187 |
3189 |
} else {
|
3188 |
3190 |
rm = (modrm & 7);
|
3189 |
3191 |
op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
|
... | ... | |
6689 |
6691 |
cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
|
6690 |
6692 |
cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
|
6691 |
6693 |
cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0");
|
|
6694 |
cpu_tmp1 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1");
|
6692 |
6695 |
#endif
|
6693 |
6696 |
/* the helpers are only registered to print debug info */
|
6694 |
6697 |
TCG_HELPER(helper_divl_EAX_T0);
|
... | ... | |
6786 |
6789 |
#endif
|
6787 |
6790 |
|
6788 |
6791 |
cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
|
|
6792 |
#if TARGET_LONG_BITS > HOST_LONG_BITS
|
|
6793 |
cpu_tmp1 = tcg_temp_new(TCG_TYPE_I64);
|
|
6794 |
#endif
|
6789 |
6795 |
|
6790 |
6796 |
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
|
6791 |
6797 |
|