Commit 465e983875be3d7c8cb8f53628e090f15417b4f7
1 parent
b854608e
SSE3 support (Joachim Henke)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1839 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
102 additions
and
16 deletions
target-i386/cpu.h
target-i386/exec.h
... | ... | @@ -260,6 +260,8 @@ static inline void stfl(target_ulong ptr, float v) |
260 | 260 | /* use long double functions */ |
261 | 261 | #define floatx_to_int32 floatx80_to_int32 |
262 | 262 | #define floatx_to_int64 floatx80_to_int64 |
263 | +#define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero | |
264 | +#define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero | |
263 | 265 | #define floatx_abs floatx80_abs |
264 | 266 | #define floatx_chs floatx80_chs |
265 | 267 | #define floatx_round_to_int floatx80_round_to_int |
... | ... | @@ -278,6 +280,8 @@ static inline void stfl(target_ulong ptr, float v) |
278 | 280 | #else |
279 | 281 | #define floatx_to_int32 float64_to_int32 |
280 | 282 | #define floatx_to_int64 float64_to_int64 |
283 | +#define floatx_to_int32_round_to_zero float64_to_int32_round_to_zero | |
284 | +#define floatx_to_int64_round_to_zero float64_to_int64_round_to_zero | |
281 | 285 | #define floatx_abs float64_abs |
282 | 286 | #define floatx_chs float64_chs |
283 | 287 | #define floatx_round_to_int float64_round_to_int | ... | ... |
target-i386/helper2.c
... | ... | @@ -108,7 +108,7 @@ CPUX86State *cpu_x86_init(void) |
108 | 108 | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | |
109 | 109 | CPUID_PAT); |
110 | 110 | env->pat = 0x0007040600070406ULL; |
111 | - env->cpuid_ext_features = 0; | |
111 | + env->cpuid_ext_features = CPUID_EXT_SSE3; | |
112 | 112 | env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP; |
113 | 113 | env->cpuid_xlevel = 0; |
114 | 114 | { | ... | ... |
target-i386/op.c
... | ... | @@ -1911,6 +1911,53 @@ void OPPROTO op_fistll_ST0_A0(void) |
1911 | 1911 | FORCE_RET(); |
1912 | 1912 | } |
1913 | 1913 | |
1914 | +void OPPROTO op_fistt_ST0_A0(void) | |
1915 | +{ | |
1916 | +#if defined(__sparc__) && !defined(__sparc_v9__) | |
1917 | + register CPU86_LDouble d asm("o0"); | |
1918 | +#else | |
1919 | + CPU86_LDouble d; | |
1920 | +#endif | |
1921 | + int val; | |
1922 | + | |
1923 | + d = ST0; | |
1924 | + val = floatx_to_int32_round_to_zero(d, &env->fp_status); | |
1925 | + if (val != (int16_t)val) | |
1926 | + val = -32768; | |
1927 | + stw(A0, val); | |
1928 | + FORCE_RET(); | |
1929 | +} | |
1930 | + | |
1931 | +void OPPROTO op_fisttl_ST0_A0(void) | |
1932 | +{ | |
1933 | +#if defined(__sparc__) && !defined(__sparc_v9__) | |
1934 | + register CPU86_LDouble d asm("o0"); | |
1935 | +#else | |
1936 | + CPU86_LDouble d; | |
1937 | +#endif | |
1938 | + int val; | |
1939 | + | |
1940 | + d = ST0; | |
1941 | + val = floatx_to_int32_round_to_zero(d, &env->fp_status); | |
1942 | + stl(A0, val); | |
1943 | + FORCE_RET(); | |
1944 | +} | |
1945 | + | |
1946 | +void OPPROTO op_fisttll_ST0_A0(void) | |
1947 | +{ | |
1948 | +#if defined(__sparc__) && !defined(__sparc_v9__) | |
1949 | + register CPU86_LDouble d asm("o0"); | |
1950 | +#else | |
1951 | + CPU86_LDouble d; | |
1952 | +#endif | |
1953 | + int64_t val; | |
1954 | + | |
1955 | + d = ST0; | |
1956 | + val = floatx_to_int64_round_to_zero(d, &env->fp_status); | |
1957 | + stq(A0, val); | |
1958 | + FORCE_RET(); | |
1959 | +} | |
1960 | + | |
1914 | 1961 | void OPPROTO op_fbld_ST0_A0(void) |
1915 | 1962 | { |
1916 | 1963 | helper_fbld_ST0_A0(); | ... | ... |
target-i386/translate.c
... | ... | @@ -2334,7 +2334,7 @@ static GenOpFunc2 *sse_op_table1[256][4] = { |
2334 | 2334 | /* pure SSE operations */ |
2335 | 2335 | [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */ |
2336 | 2336 | [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */ |
2337 | - [0x12] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */ | |
2337 | + [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */ | |
2338 | 2338 | [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */ |
2339 | 2339 | [0x14] = { gen_op_punpckldq_xmm, gen_op_punpcklqdq_xmm }, |
2340 | 2340 | [0x15] = { gen_op_punpckhdq_xmm, gen_op_punpckhqdq_xmm }, |
... | ... | @@ -2436,7 +2436,7 @@ static GenOpFunc2 *sse_op_table1[256][4] = { |
2436 | 2436 | [0xed] = MMX_OP2(paddsw), |
2437 | 2437 | [0xee] = MMX_OP2(pmaxsw), |
2438 | 2438 | [0xef] = MMX_OP2(pxor), |
2439 | - [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu (PNI) */ | |
2439 | + [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */ | |
2440 | 2440 | [0xf1] = MMX_OP2(psllw), |
2441 | 2441 | [0xf2] = MMX_OP2(pslld), |
2442 | 2442 | [0xf3] = MMX_OP2(psllq), |
... | ... | @@ -2563,8 +2563,8 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) |
2563 | 2563 | case 0x1e7: /* movntdq */ |
2564 | 2564 | case 0x02b: /* movntps */ |
2565 | 2565 | case 0x12b: /* movntps */ |
2566 | - case 0x2f0: /* lddqu */ | |
2567 | - if (mod == 3) | |
2566 | + case 0x3f0: /* lddqu */ | |
2567 | + if (mod == 3) | |
2568 | 2568 | goto illegal_op; |
2569 | 2569 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
2570 | 2570 | gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg])); |
... | ... | @@ -2642,6 +2642,34 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) |
2642 | 2642 | offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1))); |
2643 | 2643 | } |
2644 | 2644 | break; |
2645 | + case 0x212: /* movsldup */ | |
2646 | + if (mod != 3) { | |
2647 | + gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | |
2648 | + gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg])); | |
2649 | + } else { | |
2650 | + rm = (modrm & 7) | REX_B(s); | |
2651 | + gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)), | |
2652 | + offsetof(CPUX86State,xmm_regs[rm].XMM_L(0))); | |
2653 | + gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)), | |
2654 | + offsetof(CPUX86State,xmm_regs[rm].XMM_L(2))); | |
2655 | + } | |
2656 | + gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)), | |
2657 | + offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); | |
2658 | + gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)), | |
2659 | + offsetof(CPUX86State,xmm_regs[reg].XMM_L(2))); | |
2660 | + break; | |
2661 | + case 0x312: /* movddup */ | |
2662 | + if (mod != 3) { | |
2663 | + gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | |
2664 | + gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); | |
2665 | + } else { | |
2666 | + rm = (modrm & 7) | REX_B(s); | |
2667 | + gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)), | |
2668 | + offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0))); | |
2669 | + } | |
2670 | + gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)), | |
2671 | + offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0))); | |
2672 | + break; | |
2645 | 2673 | case 0x016: /* movhps */ |
2646 | 2674 | case 0x116: /* movhpd */ |
2647 | 2675 | if (mod != 3) { |
... | ... | @@ -4278,16 +4306,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4278 | 4306 | case 0x08: /* flds */ |
4279 | 4307 | case 0x0a: /* fsts */ |
4280 | 4308 | case 0x0b: /* fstps */ |
4281 | - case 0x18: /* fildl */ | |
4282 | - case 0x1a: /* fistl */ | |
4283 | - case 0x1b: /* fistpl */ | |
4284 | - case 0x28: /* fldl */ | |
4285 | - case 0x2a: /* fstl */ | |
4286 | - case 0x2b: /* fstpl */ | |
4287 | - case 0x38: /* filds */ | |
4288 | - case 0x3a: /* fists */ | |
4289 | - case 0x3b: /* fistps */ | |
4290 | - | |
4309 | + case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */ | |
4310 | + case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */ | |
4311 | + case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */ | |
4291 | 4312 | switch(op & 7) { |
4292 | 4313 | case 0: |
4293 | 4314 | switch(op >> 4) { |
... | ... | @@ -4306,6 +4327,20 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4306 | 4327 | break; |
4307 | 4328 | } |
4308 | 4329 | break; |
4330 | + case 1: | |
4331 | + switch(op >> 4) { | |
4332 | + case 1: | |
4333 | + gen_op_fisttl_ST0_A0(); | |
4334 | + break; | |
4335 | + case 2: | |
4336 | + gen_op_fisttll_ST0_A0(); | |
4337 | + break; | |
4338 | + case 3: | |
4339 | + default: | |
4340 | + gen_op_fistt_ST0_A0(); | |
4341 | + } | |
4342 | + gen_op_fpop(); | |
4343 | + break; | |
4309 | 4344 | default: |
4310 | 4345 | switch(op >> 4) { |
4311 | 4346 | case 0: | ... | ... |