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) |