Commit 214c465f86138aadd7f59f050a188d4362bd3ab8
1 parent
2b0233ab
Switch the standard multiplication instructions to TCG.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4740 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
166 additions
and
94 deletions
target-mips/exec.h
target-mips/helper.h
target-mips/op.c
... | ... | @@ -68,18 +68,6 @@ |
68 | 68 | |
69 | 69 | /* 64 bits arithmetic */ |
70 | 70 | #if TARGET_LONG_BITS > HOST_LONG_BITS |
71 | -void op_mult (void) | |
72 | -{ | |
73 | - CALL_FROM_TB0(do_mult); | |
74 | - FORCE_RET(); | |
75 | -} | |
76 | - | |
77 | -void op_multu (void) | |
78 | -{ | |
79 | - CALL_FROM_TB0(do_multu); | |
80 | - FORCE_RET(); | |
81 | -} | |
82 | - | |
83 | 71 | void op_madd (void) |
84 | 72 | { |
85 | 73 | CALL_FROM_TB0(do_madd); |
... | ... | @@ -214,54 +202,6 @@ static always_inline void set_HI_LOT0 (uint64_t HILO) |
214 | 202 | env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); |
215 | 203 | } |
216 | 204 | |
217 | -void op_mult (void) | |
218 | -{ | |
219 | - set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); | |
220 | - FORCE_RET(); | |
221 | -} | |
222 | - | |
223 | -void op_multu (void) | |
224 | -{ | |
225 | - set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); | |
226 | - FORCE_RET(); | |
227 | -} | |
228 | - | |
229 | -void op_madd (void) | |
230 | -{ | |
231 | - int64_t tmp; | |
232 | - | |
233 | - tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); | |
234 | - set_HILO((int64_t)get_HILO() + tmp); | |
235 | - FORCE_RET(); | |
236 | -} | |
237 | - | |
238 | -void op_maddu (void) | |
239 | -{ | |
240 | - uint64_t tmp; | |
241 | - | |
242 | - tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); | |
243 | - set_HILO(get_HILO() + tmp); | |
244 | - FORCE_RET(); | |
245 | -} | |
246 | - | |
247 | -void op_msub (void) | |
248 | -{ | |
249 | - int64_t tmp; | |
250 | - | |
251 | - tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); | |
252 | - set_HILO((int64_t)get_HILO() - tmp); | |
253 | - FORCE_RET(); | |
254 | -} | |
255 | - | |
256 | -void op_msubu (void) | |
257 | -{ | |
258 | - uint64_t tmp; | |
259 | - | |
260 | - tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); | |
261 | - set_HILO(get_HILO() - tmp); | |
262 | - FORCE_RET(); | |
263 | -} | |
264 | - | |
265 | 205 | /* Multiplication variants of the vr54xx. */ |
266 | 206 | void op_muls (void) |
267 | 207 | { |
... | ... | @@ -349,20 +289,6 @@ void op_mulshiu (void) |
349 | 289 | |
350 | 290 | #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ |
351 | 291 | |
352 | -#if defined(TARGET_MIPS64) | |
353 | -void op_dmult (void) | |
354 | -{ | |
355 | - CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); | |
356 | - FORCE_RET(); | |
357 | -} | |
358 | - | |
359 | -void op_dmultu (void) | |
360 | -{ | |
361 | - CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); | |
362 | - FORCE_RET(); | |
363 | -} | |
364 | -#endif | |
365 | - | |
366 | 292 | /* CP1 functions */ |
367 | 293 | #if 0 |
368 | 294 | # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env) | ... | ... |
target-mips/op_helper.c
... | ... | @@ -192,16 +192,6 @@ static always_inline void set_HI_LOT0 (uint64_t HILO) |
192 | 192 | env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); |
193 | 193 | } |
194 | 194 | |
195 | -void do_mult (void) | |
196 | -{ | |
197 | - set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); | |
198 | -} | |
199 | - | |
200 | -void do_multu (void) | |
201 | -{ | |
202 | - set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); | |
203 | -} | |
204 | - | |
205 | 195 | void do_madd (void) |
206 | 196 | { |
207 | 197 | int64_t tmp; |
... | ... | @@ -306,6 +296,18 @@ void do_mulshiu (void) |
306 | 296 | } |
307 | 297 | #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ |
308 | 298 | |
299 | +#ifdef TARGET_MIPS64 | |
300 | +void do_dmult (void) | |
301 | +{ | |
302 | + muls64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); | |
303 | +} | |
304 | + | |
305 | +void do_dmultu (void) | |
306 | +{ | |
307 | + mulu64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); | |
308 | +} | |
309 | +#endif | |
310 | + | |
309 | 311 | #ifdef CONFIG_USER_ONLY |
310 | 312 | void do_mfc0_random (void) |
311 | 313 | { | ... | ... |
target-mips/translate.c
... | ... | @@ -1941,11 +1941,47 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, |
1941 | 1941 | opn = "divu"; |
1942 | 1942 | break; |
1943 | 1943 | case OPC_MULT: |
1944 | - gen_op_mult(); | |
1944 | + { | |
1945 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); | |
1946 | + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); | |
1947 | + | |
1948 | + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); | |
1949 | + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); | |
1950 | + tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); | |
1951 | + tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); | |
1952 | + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); | |
1953 | + tcg_temp_free(r_tmp2); | |
1954 | + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); | |
1955 | + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); | |
1956 | + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); | |
1957 | + tcg_temp_free(r_tmp1); | |
1958 | + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); | |
1959 | + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); | |
1960 | + gen_store_LO(cpu_T[0], 0); | |
1961 | + gen_store_HI(cpu_T[1], 0); | |
1962 | + } | |
1945 | 1963 | opn = "mult"; |
1946 | 1964 | break; |
1947 | 1965 | case OPC_MULTU: |
1948 | - gen_op_multu(); | |
1966 | + { | |
1967 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); | |
1968 | + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); | |
1969 | + | |
1970 | + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); | |
1971 | + tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); | |
1972 | + tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]); | |
1973 | + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]); | |
1974 | + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); | |
1975 | + tcg_temp_free(r_tmp2); | |
1976 | + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); | |
1977 | + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); | |
1978 | + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); | |
1979 | + tcg_temp_free(r_tmp1); | |
1980 | + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); | |
1981 | + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); | |
1982 | + gen_store_LO(cpu_T[0], 0); | |
1983 | + gen_store_HI(cpu_T[1], 0); | |
1984 | + } | |
1949 | 1985 | opn = "multu"; |
1950 | 1986 | break; |
1951 | 1987 | #if defined(TARGET_MIPS64) |
... | ... | @@ -2003,28 +2039,136 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, |
2003 | 2039 | opn = "ddivu"; |
2004 | 2040 | break; |
2005 | 2041 | case OPC_DMULT: |
2006 | - gen_op_dmult(); | |
2042 | + tcg_gen_helper_0_0(do_dmult); | |
2007 | 2043 | opn = "dmult"; |
2008 | 2044 | break; |
2009 | 2045 | case OPC_DMULTU: |
2010 | - gen_op_dmultu(); | |
2046 | + tcg_gen_helper_0_0(do_dmultu); | |
2011 | 2047 | opn = "dmultu"; |
2012 | 2048 | break; |
2013 | 2049 | #endif |
2014 | 2050 | case OPC_MADD: |
2015 | - gen_op_madd(); | |
2051 | + { | |
2052 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); | |
2053 | + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); | |
2054 | + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); | |
2055 | + | |
2056 | + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); | |
2057 | + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); | |
2058 | + tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); | |
2059 | + tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); | |
2060 | + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); | |
2061 | + gen_load_LO(cpu_T[0], 0); | |
2062 | + gen_load_HI(cpu_T[1], 0); | |
2063 | + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); | |
2064 | + tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); | |
2065 | + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); | |
2066 | + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); | |
2067 | + tcg_temp_free(r_tmp3); | |
2068 | + tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2); | |
2069 | + tcg_temp_free(r_tmp2); | |
2070 | + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); | |
2071 | + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); | |
2072 | + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); | |
2073 | + tcg_temp_free(r_tmp1); | |
2074 | + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); | |
2075 | + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); | |
2076 | + gen_store_LO(cpu_T[0], 0); | |
2077 | + gen_store_HI(cpu_T[1], 0); | |
2078 | + } | |
2016 | 2079 | opn = "madd"; |
2017 | 2080 | break; |
2018 | 2081 | case OPC_MADDU: |
2019 | - gen_op_maddu(); | |
2082 | + { | |
2083 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); | |
2084 | + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); | |
2085 | + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); | |
2086 | + | |
2087 | + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); | |
2088 | + tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); | |
2089 | + tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]); | |
2090 | + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]); | |
2091 | + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); | |
2092 | + gen_load_LO(cpu_T[0], 0); | |
2093 | + gen_load_HI(cpu_T[1], 0); | |
2094 | + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); | |
2095 | + tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); | |
2096 | + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); | |
2097 | + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); | |
2098 | + tcg_temp_free(r_tmp3); | |
2099 | + tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2); | |
2100 | + tcg_temp_free(r_tmp2); | |
2101 | + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); | |
2102 | + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); | |
2103 | + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); | |
2104 | + tcg_temp_free(r_tmp1); | |
2105 | + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); | |
2106 | + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); | |
2107 | + gen_store_LO(cpu_T[0], 0); | |
2108 | + gen_store_HI(cpu_T[1], 0); | |
2109 | + } | |
2020 | 2110 | opn = "maddu"; |
2021 | 2111 | break; |
2022 | 2112 | case OPC_MSUB: |
2023 | - gen_op_msub(); | |
2113 | + { | |
2114 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); | |
2115 | + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); | |
2116 | + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); | |
2117 | + | |
2118 | + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); | |
2119 | + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); | |
2120 | + tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); | |
2121 | + tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); | |
2122 | + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); | |
2123 | + gen_load_LO(cpu_T[0], 0); | |
2124 | + gen_load_HI(cpu_T[1], 0); | |
2125 | + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); | |
2126 | + tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); | |
2127 | + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); | |
2128 | + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); | |
2129 | + tcg_temp_free(r_tmp3); | |
2130 | + tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2); | |
2131 | + tcg_temp_free(r_tmp2); | |
2132 | + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); | |
2133 | + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); | |
2134 | + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); | |
2135 | + tcg_temp_free(r_tmp1); | |
2136 | + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); | |
2137 | + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); | |
2138 | + gen_store_LO(cpu_T[0], 0); | |
2139 | + gen_store_HI(cpu_T[1], 0); | |
2140 | + } | |
2024 | 2141 | opn = "msub"; |
2025 | 2142 | break; |
2026 | 2143 | case OPC_MSUBU: |
2027 | - gen_op_msubu(); | |
2144 | + { | |
2145 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); | |
2146 | + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); | |
2147 | + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); | |
2148 | + | |
2149 | + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); | |
2150 | + tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); | |
2151 | + tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]); | |
2152 | + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]); | |
2153 | + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); | |
2154 | + gen_load_LO(cpu_T[0], 0); | |
2155 | + gen_load_HI(cpu_T[1], 0); | |
2156 | + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); | |
2157 | + tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); | |
2158 | + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); | |
2159 | + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); | |
2160 | + tcg_temp_free(r_tmp3); | |
2161 | + tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2); | |
2162 | + tcg_temp_free(r_tmp2); | |
2163 | + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); | |
2164 | + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); | |
2165 | + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); | |
2166 | + tcg_temp_free(r_tmp1); | |
2167 | + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); | |
2168 | + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); | |
2169 | + gen_store_LO(cpu_T[0], 0); | |
2170 | + gen_store_HI(cpu_T[1], 0); | |
2171 | + } | |
2028 | 2172 | opn = "msubu"; |
2029 | 2173 | break; |
2030 | 2174 | default: | ... | ... |