Commit 893f986502196aeb43d176161179c3ff22a7e0a8
1 parent
eaa728ee
Honour current_tc for MIPS M{T,F}{HI,LO}, by Richard Sandiford.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4604 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
46 additions
and
45 deletions
target-mips/cpu.h
@@ -159,6 +159,7 @@ struct CPUMIPSState { | @@ -159,6 +159,7 @@ struct CPUMIPSState { | ||
159 | CPUMIPSFPUContext *fpu; | 159 | CPUMIPSFPUContext *fpu; |
160 | uint32_t current_tc; | 160 | uint32_t current_tc; |
161 | target_ulong *current_tc_gprs; | 161 | target_ulong *current_tc_gprs; |
162 | + target_ulong *current_tc_hi; | ||
162 | 163 | ||
163 | uint32_t SEGBITS; | 164 | uint32_t SEGBITS; |
164 | target_ulong SEGMask; | 165 | target_ulong SEGMask; |
target-mips/translate.c
@@ -423,7 +423,7 @@ enum { | @@ -423,7 +423,7 @@ enum { | ||
423 | }; | 423 | }; |
424 | 424 | ||
425 | /* global register indices */ | 425 | /* global register indices */ |
426 | -static TCGv cpu_env, current_tc_gprs, cpu_T[2]; | 426 | +static TCGv cpu_env, current_tc_gprs, current_tc_hi, cpu_T[2]; |
427 | 427 | ||
428 | /* The code generator doesn't like lots of temporaries, so maintain our own | 428 | /* The code generator doesn't like lots of temporaries, so maintain our own |
429 | cache for reuse within a function. */ | 429 | cache for reuse within a function. */ |
@@ -531,6 +531,33 @@ static inline void gen_store_gpr (TCGv t, int reg) | @@ -531,6 +531,33 @@ static inline void gen_store_gpr (TCGv t, int reg) | ||
531 | tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg); | 531 | tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg); |
532 | } | 532 | } |
533 | 533 | ||
534 | +/* Moves to/from HI and LO registers. */ | ||
535 | +static inline void gen_load_LO (TCGv t, int reg) | ||
536 | +{ | ||
537 | + tcg_gen_ld_tl(t, current_tc_hi, | ||
538 | + offsetof(CPUState, LO) | ||
539 | + - offsetof(CPUState, HI) | ||
540 | + + sizeof(target_ulong) * reg); | ||
541 | +} | ||
542 | + | ||
543 | +static inline void gen_store_LO (TCGv t, int reg) | ||
544 | +{ | ||
545 | + tcg_gen_st_tl(t, current_tc_hi, | ||
546 | + offsetof(CPUState, LO) | ||
547 | + - offsetof(CPUState, HI) | ||
548 | + + sizeof(target_ulong) * reg); | ||
549 | +} | ||
550 | + | ||
551 | +static inline void gen_load_HI (TCGv t, int reg) | ||
552 | +{ | ||
553 | + tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg); | ||
554 | +} | ||
555 | + | ||
556 | +static inline void gen_store_HI (TCGv t, int reg) | ||
557 | +{ | ||
558 | + tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg); | ||
559 | +} | ||
560 | + | ||
534 | /* Moves to/from shadow registers. */ | 561 | /* Moves to/from shadow registers. */ |
535 | static inline void gen_load_srsgpr (TCGv t, int reg) | 562 | static inline void gen_load_srsgpr (TCGv t, int reg) |
536 | { | 563 | { |
@@ -1834,23 +1861,23 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) | @@ -1834,23 +1861,23 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) | ||
1834 | } | 1861 | } |
1835 | switch (opc) { | 1862 | switch (opc) { |
1836 | case OPC_MFHI: | 1863 | case OPC_MFHI: |
1837 | - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[0])); | 1864 | + gen_load_HI(cpu_T[0], 0); |
1838 | gen_store_gpr(cpu_T[0], reg); | 1865 | gen_store_gpr(cpu_T[0], reg); |
1839 | opn = "mfhi"; | 1866 | opn = "mfhi"; |
1840 | break; | 1867 | break; |
1841 | case OPC_MFLO: | 1868 | case OPC_MFLO: |
1842 | - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[0])); | 1869 | + gen_load_LO(cpu_T[0], 0); |
1843 | gen_store_gpr(cpu_T[0], reg); | 1870 | gen_store_gpr(cpu_T[0], reg); |
1844 | opn = "mflo"; | 1871 | opn = "mflo"; |
1845 | break; | 1872 | break; |
1846 | case OPC_MTHI: | 1873 | case OPC_MTHI: |
1847 | gen_load_gpr(cpu_T[0], reg); | 1874 | gen_load_gpr(cpu_T[0], reg); |
1848 | - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[0])); | 1875 | + gen_store_HI(cpu_T[0], 0); |
1849 | opn = "mthi"; | 1876 | opn = "mthi"; |
1850 | break; | 1877 | break; |
1851 | case OPC_MTLO: | 1878 | case OPC_MTLO: |
1852 | gen_load_gpr(cpu_T[0], reg); | 1879 | gen_load_gpr(cpu_T[0], reg); |
1853 | - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[0])); | 1880 | + gen_store_LO(cpu_T[0], 0); |
1854 | opn = "mtlo"; | 1881 | opn = "mtlo"; |
1855 | break; | 1882 | break; |
1856 | default: | 1883 | default: |
@@ -1878,9 +1905,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | @@ -1878,9 +1905,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | ||
1878 | TCGv r_tmp1 = new_tmp(); | 1905 | TCGv r_tmp1 = new_tmp(); |
1879 | TCGv r_tmp2 = new_tmp(); | 1906 | TCGv r_tmp2 = new_tmp(); |
1880 | TCGv r_tmp3 = new_tmp(); | 1907 | TCGv r_tmp3 = new_tmp(); |
1881 | - TCGv r_tc_off = new_tmp(); | ||
1882 | - TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL); | ||
1883 | - TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR); | ||
1884 | 1908 | ||
1885 | tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]); | 1909 | tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]); |
1886 | tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]); | 1910 | tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]); |
@@ -1888,16 +1912,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | @@ -1888,16 +1912,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | ||
1888 | tcg_gen_rem_i32(r_tmp1, r_tmp1, r_tmp2); | 1912 | tcg_gen_rem_i32(r_tmp1, r_tmp1, r_tmp2); |
1889 | tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3); | 1913 | tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3); |
1890 | tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1); | 1914 | tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1); |
1915 | + gen_store_LO(cpu_T[0], 0); | ||
1916 | + gen_store_HI(cpu_T[1], 0); | ||
1891 | dead_tmp(r_tmp1); | 1917 | dead_tmp(r_tmp1); |
1892 | dead_tmp(r_tmp2); | 1918 | dead_tmp(r_tmp2); |
1893 | dead_tmp(r_tmp3); | 1919 | dead_tmp(r_tmp3); |
1894 | - tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc)); | ||
1895 | - tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong)); | ||
1896 | - tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off); | ||
1897 | - tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl); | ||
1898 | - tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO)); | ||
1899 | - tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI)); | ||
1900 | - dead_tmp(r_tc_off); | ||
1901 | } | 1920 | } |
1902 | gen_set_label(l1); | 1921 | gen_set_label(l1); |
1903 | } | 1922 | } |
@@ -1912,9 +1931,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | @@ -1912,9 +1931,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | ||
1912 | TCGv r_tmp1 = new_tmp(); | 1931 | TCGv r_tmp1 = new_tmp(); |
1913 | TCGv r_tmp2 = new_tmp(); | 1932 | TCGv r_tmp2 = new_tmp(); |
1914 | TCGv r_tmp3 = new_tmp(); | 1933 | TCGv r_tmp3 = new_tmp(); |
1915 | - TCGv r_tc_off = new_tmp(); | ||
1916 | - TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL); | ||
1917 | - TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR); | ||
1918 | 1934 | ||
1919 | tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]); | 1935 | tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]); |
1920 | tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]); | 1936 | tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]); |
@@ -1922,16 +1938,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | @@ -1922,16 +1938,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | ||
1922 | tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2); | 1938 | tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2); |
1923 | tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3); | 1939 | tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3); |
1924 | tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1); | 1940 | tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1); |
1941 | + gen_store_LO(cpu_T[0], 0); | ||
1942 | + gen_store_HI(cpu_T[1], 0); | ||
1925 | dead_tmp(r_tmp1); | 1943 | dead_tmp(r_tmp1); |
1926 | dead_tmp(r_tmp2); | 1944 | dead_tmp(r_tmp2); |
1927 | dead_tmp(r_tmp3); | 1945 | dead_tmp(r_tmp3); |
1928 | - tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc)); | ||
1929 | - tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong)); | ||
1930 | - tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off); | ||
1931 | - tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl); | ||
1932 | - tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO)); | ||
1933 | - tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI)); | ||
1934 | - dead_tmp(r_tc_off); | ||
1935 | } | 1946 | } |
1936 | gen_set_label(l1); | 1947 | gen_set_label(l1); |
1937 | } | 1948 | } |
@@ -1952,9 +1963,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | @@ -1952,9 +1963,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | ||
1952 | 1963 | ||
1953 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); | 1964 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); |
1954 | { | 1965 | { |
1955 | - TCGv r_tc_off = new_tmp(); | ||
1956 | - TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL); | ||
1957 | - TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR); | ||
1958 | int l2 = gen_new_label(); | 1966 | int l2 = gen_new_label(); |
1959 | int l3 = gen_new_label(); | 1967 | int l3 = gen_new_label(); |
1960 | 1968 | ||
@@ -1968,13 +1976,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | @@ -1968,13 +1976,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | ||
1968 | tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]); | 1976 | tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]); |
1969 | gen_set_label(l3); | 1977 | gen_set_label(l3); |
1970 | 1978 | ||
1971 | - tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc)); | ||
1972 | - tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong)); | ||
1973 | - tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off); | ||
1974 | - tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl); | ||
1975 | - tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO)); | ||
1976 | - tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI)); | ||
1977 | - dead_tmp(r_tc_off); | 1979 | + gen_store_LO(cpu_T[0], 0); |
1980 | + gen_store_HI(cpu_T[1], 0); | ||
1978 | } | 1981 | } |
1979 | gen_set_label(l1); | 1982 | gen_set_label(l1); |
1980 | } | 1983 | } |
@@ -1988,19 +1991,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | @@ -1988,19 +1991,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | ||
1988 | { | 1991 | { |
1989 | TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); | 1992 | TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); |
1990 | TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); | 1993 | TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); |
1991 | - TCGv r_tc_off = new_tmp(); | ||
1992 | - TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL); | ||
1993 | - TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR); | ||
1994 | 1994 | ||
1995 | tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]); | 1995 | tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]); |
1996 | tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]); | 1996 | tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]); |
1997 | - tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc)); | ||
1998 | - tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong)); | ||
1999 | - tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off); | ||
2000 | - tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl); | ||
2001 | - tcg_gen_st_tl(r_tmp1, r_ptr, offsetof(CPUState, LO)); | ||
2002 | - tcg_gen_st_tl(r_tmp2, r_ptr, offsetof(CPUState, HI)); | ||
2003 | - dead_tmp(r_tc_off); | 1997 | + gen_store_LO(r_tmp1, 0); |
1998 | + gen_store_HI(r_tmp2, 0); | ||
2004 | } | 1999 | } |
2005 | gen_set_label(l1); | 2000 | gen_set_label(l1); |
2006 | } | 2001 | } |
@@ -7512,6 +7507,10 @@ static void mips_tcg_init(void) | @@ -7512,6 +7507,10 @@ static void mips_tcg_init(void) | ||
7512 | TCG_AREG0, | 7507 | TCG_AREG0, |
7513 | offsetof(CPUState, current_tc_gprs), | 7508 | offsetof(CPUState, current_tc_gprs), |
7514 | "current_tc_gprs"); | 7509 | "current_tc_gprs"); |
7510 | + current_tc_hi = tcg_global_mem_new(TCG_TYPE_PTR, | ||
7511 | + TCG_AREG0, | ||
7512 | + offsetof(CPUState, current_tc_hi), | ||
7513 | + "current_tc_hi"); | ||
7515 | #if TARGET_LONG_BITS > HOST_LONG_BITS | 7514 | #if TARGET_LONG_BITS > HOST_LONG_BITS |
7516 | cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, | 7515 | cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, |
7517 | TCG_AREG0, offsetof(CPUState, t0), "T0"); | 7516 | TCG_AREG0, offsetof(CPUState, t0), "T0"); |
target-mips/translate_init.c
@@ -547,6 +547,7 @@ static int cpu_mips_register (CPUMIPSState *env, const mips_def_t *def) | @@ -547,6 +547,7 @@ static int cpu_mips_register (CPUMIPSState *env, const mips_def_t *def) | ||
547 | env->CP0_SRSCtl = def->CP0_SRSCtl; | 547 | env->CP0_SRSCtl = def->CP0_SRSCtl; |
548 | env->current_tc = 0; | 548 | env->current_tc = 0; |
549 | env->current_tc_gprs = &env->gpr[env->current_tc][0]; | 549 | env->current_tc_gprs = &env->gpr[env->current_tc][0]; |
550 | + env->current_tc_hi = &env->HI[env->current_tc][0]; | ||
550 | env->SEGBITS = def->SEGBITS; | 551 | env->SEGBITS = def->SEGBITS; |
551 | env->SEGMask = (target_ulong)((1ULL << def->SEGBITS) - 1); | 552 | env->SEGMask = (target_ulong)((1ULL << def->SEGBITS) - 1); |
552 | #if defined(TARGET_MIPS64) | 553 | #if defined(TARGET_MIPS64) |