Revision 8686c490 target-i386/translate.c
b/target-i386/translate.c | ||
---|---|---|
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 |
|
Also available in: Unified diff