Commit 893f986502196aeb43d176161179c3ff22a7e0a8

Authored by ths
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
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)