Commit 214c465f86138aadd7f59f050a188d4362bd3ab8

Authored by ths
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
target-mips/exec.h
@@ -49,8 +49,6 @@ register target_ulong T1 asm(AREG2); @@ -49,8 +49,6 @@ register target_ulong T1 asm(AREG2);
49 #endif /* !defined(CONFIG_USER_ONLY) */ 49 #endif /* !defined(CONFIG_USER_ONLY) */
50 50
51 #if TARGET_LONG_BITS > HOST_LONG_BITS 51 #if TARGET_LONG_BITS > HOST_LONG_BITS
52 -void do_mult (void);  
53 -void do_multu (void);  
54 void do_madd (void); 52 void do_madd (void);
55 void do_maddu (void); 53 void do_maddu (void);
56 void do_msub (void); 54 void do_msub (void);
target-mips/helper.h
@@ -11,6 +11,8 @@ DEF_HELPER(void, do_clz, (void)) @@ -11,6 +11,8 @@ DEF_HELPER(void, do_clz, (void))
11 #ifdef TARGET_MIPS64 11 #ifdef TARGET_MIPS64
12 DEF_HELPER(void, do_dclo, (void)) 12 DEF_HELPER(void, do_dclo, (void))
13 DEF_HELPER(void, do_dclz, (void)) 13 DEF_HELPER(void, do_dclz, (void))
  14 +DEF_HELPER(void, do_dmult, (void))
  15 +DEF_HELPER(void, do_dmultu, (void))
14 #endif 16 #endif
15 17
16 /* CP0 helpers */ 18 /* CP0 helpers */
target-mips/op.c
@@ -68,18 +68,6 @@ @@ -68,18 +68,6 @@
68 68
69 /* 64 bits arithmetic */ 69 /* 64 bits arithmetic */
70 #if TARGET_LONG_BITS > HOST_LONG_BITS 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 void op_madd (void) 71 void op_madd (void)
84 { 72 {
85 CALL_FROM_TB0(do_madd); 73 CALL_FROM_TB0(do_madd);
@@ -214,54 +202,6 @@ static always_inline void set_HI_LOT0 (uint64_t HILO) @@ -214,54 +202,6 @@ static always_inline void set_HI_LOT0 (uint64_t HILO)
214 env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); 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 /* Multiplication variants of the vr54xx. */ 205 /* Multiplication variants of the vr54xx. */
266 void op_muls (void) 206 void op_muls (void)
267 { 207 {
@@ -349,20 +289,6 @@ void op_mulshiu (void) @@ -349,20 +289,6 @@ void op_mulshiu (void)
349 289
350 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ 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 /* CP1 functions */ 292 /* CP1 functions */
367 #if 0 293 #if 0
368 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env) 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,16 +192,6 @@ static always_inline void set_HI_LOT0 (uint64_t HILO)
192 env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); 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 void do_madd (void) 195 void do_madd (void)
206 { 196 {
207 int64_t tmp; 197 int64_t tmp;
@@ -306,6 +296,18 @@ void do_mulshiu (void) @@ -306,6 +296,18 @@ void do_mulshiu (void)
306 } 296 }
307 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ 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 #ifdef CONFIG_USER_ONLY 311 #ifdef CONFIG_USER_ONLY
310 void do_mfc0_random (void) 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,11 +1941,47 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1941 opn = "divu"; 1941 opn = "divu";
1942 break; 1942 break;
1943 case OPC_MULT: 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 opn = "mult"; 1963 opn = "mult";
1946 break; 1964 break;
1947 case OPC_MULTU: 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 opn = "multu"; 1985 opn = "multu";
1950 break; 1986 break;
1951 #if defined(TARGET_MIPS64) 1987 #if defined(TARGET_MIPS64)
@@ -2003,28 +2039,136 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, @@ -2003,28 +2039,136 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2003 opn = "ddivu"; 2039 opn = "ddivu";
2004 break; 2040 break;
2005 case OPC_DMULT: 2041 case OPC_DMULT:
2006 - gen_op_dmult(); 2042 + tcg_gen_helper_0_0(do_dmult);
2007 opn = "dmult"; 2043 opn = "dmult";
2008 break; 2044 break;
2009 case OPC_DMULTU: 2045 case OPC_DMULTU:
2010 - gen_op_dmultu(); 2046 + tcg_gen_helper_0_0(do_dmultu);
2011 opn = "dmultu"; 2047 opn = "dmultu";
2012 break; 2048 break;
2013 #endif 2049 #endif
2014 case OPC_MADD: 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 opn = "madd"; 2079 opn = "madd";
2017 break; 2080 break;
2018 case OPC_MADDU: 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 opn = "maddu"; 2110 opn = "maddu";
2021 break; 2111 break;
2022 case OPC_MSUB: 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 opn = "msub"; 2141 opn = "msub";
2025 break; 2142 break;
2026 case OPC_MSUBU: 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 opn = "msubu"; 2172 opn = "msubu";
2029 break; 2173 break;
2030 default: 2174 default: