Revision 893f9865 target-mips/translate.c
b/target-mips/translate.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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"); |
Also available in: Unified diff