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