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
target-mips/translate.c
| ... | ... | @@ -423,7 +423,7 @@ enum { |
| 423 | 423 | }; |
| 424 | 424 | |
| 425 | 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 | 428 | /* The code generator doesn't like lots of temporaries, so maintain our own |
| 429 | 429 | cache for reuse within a function. */ |
| ... | ... | @@ -531,6 +531,33 @@ static inline void gen_store_gpr (TCGv t, int reg) |
| 531 | 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 | 561 | /* Moves to/from shadow registers. */ |
| 535 | 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 | 1861 | } |
| 1835 | 1862 | switch (opc) { |
| 1836 | 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 | 1865 | gen_store_gpr(cpu_T[0], reg); |
| 1839 | 1866 | opn = "mfhi"; |
| 1840 | 1867 | break; |
| 1841 | 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 | 1870 | gen_store_gpr(cpu_T[0], reg); |
| 1844 | 1871 | opn = "mflo"; |
| 1845 | 1872 | break; |
| 1846 | 1873 | case OPC_MTHI: |
| 1847 | 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 | 1876 | opn = "mthi"; |
| 1850 | 1877 | break; |
| 1851 | 1878 | case OPC_MTLO: |
| 1852 | 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 | 1881 | opn = "mtlo"; |
| 1855 | 1882 | break; |
| 1856 | 1883 | default: |
| ... | ... | @@ -1878,9 +1905,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, |
| 1878 | 1905 | TCGv r_tmp1 = new_tmp(); |
| 1879 | 1906 | TCGv r_tmp2 = new_tmp(); |
| 1880 | 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 | 1909 | tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]); |
| 1886 | 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 | 1912 | tcg_gen_rem_i32(r_tmp1, r_tmp1, r_tmp2); |
| 1889 | 1913 | tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3); |
| 1890 | 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 | 1917 | dead_tmp(r_tmp1); |
| 1892 | 1918 | dead_tmp(r_tmp2); |
| 1893 | 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 | 1921 | gen_set_label(l1); |
| 1903 | 1922 | } |
| ... | ... | @@ -1912,9 +1931,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, |
| 1912 | 1931 | TCGv r_tmp1 = new_tmp(); |
| 1913 | 1932 | TCGv r_tmp2 = new_tmp(); |
| 1914 | 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 | 1935 | tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]); |
| 1920 | 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 | 1938 | tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2); |
| 1923 | 1939 | tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3); |
| 1924 | 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 | 1943 | dead_tmp(r_tmp1); |
| 1926 | 1944 | dead_tmp(r_tmp2); |
| 1927 | 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 | 1947 | gen_set_label(l1); |
| 1937 | 1948 | } |
| ... | ... | @@ -1952,9 +1963,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, |
| 1952 | 1963 | |
| 1953 | 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 | 1966 | int l2 = gen_new_label(); |
| 1959 | 1967 | int l3 = gen_new_label(); |
| 1960 | 1968 | |
| ... | ... | @@ -1968,13 +1976,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, |
| 1968 | 1976 | tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]); |
| 1969 | 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 | 1982 | gen_set_label(l1); |
| 1980 | 1983 | } |
| ... | ... | @@ -1988,19 +1991,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, |
| 1988 | 1991 | { |
| 1989 | 1992 | TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); |
| 1990 | 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 | 1995 | tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]); |
| 1996 | 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 | 2000 | gen_set_label(l1); |
| 2006 | 2001 | } |
| ... | ... | @@ -7512,6 +7507,10 @@ static void mips_tcg_init(void) |
| 7512 | 7507 | TCG_AREG0, |
| 7513 | 7508 | offsetof(CPUState, current_tc_gprs), |
| 7514 | 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 | 7514 | #if TARGET_LONG_BITS > HOST_LONG_BITS |
| 7516 | 7515 | cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, |
| 7517 | 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 | 547 | env->CP0_SRSCtl = def->CP0_SRSCtl; |
| 548 | 548 | env->current_tc = 0; |
| 549 | 549 | env->current_tc_gprs = &env->gpr[env->current_tc][0]; |
| 550 | + env->current_tc_hi = &env->HI[env->current_tc][0]; | |
| 550 | 551 | env->SEGBITS = def->SEGBITS; |
| 551 | 552 | env->SEGMask = (target_ulong)((1ULL << def->SEGBITS) - 1); |
| 552 | 553 | #if defined(TARGET_MIPS64) | ... | ... |