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 49 #endif /* !defined(CONFIG_USER_ONLY) */
50 50  
51 51 #if TARGET_LONG_BITS > HOST_LONG_BITS
52   -void do_mult (void);
53   -void do_multu (void);
54 52 void do_madd (void);
55 53 void do_maddu (void);
56 54 void do_msub (void);
... ...
target-mips/helper.h
... ... @@ -11,6 +11,8 @@ DEF_HELPER(void, do_clz, (void))
11 11 #ifdef TARGET_MIPS64
12 12 DEF_HELPER(void, do_dclo, (void))
13 13 DEF_HELPER(void, do_dclz, (void))
  14 +DEF_HELPER(void, do_dmult, (void))
  15 +DEF_HELPER(void, do_dmultu, (void))
14 16 #endif
15 17  
16 18 /* CP0 helpers */
... ...
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:
... ...