Commit 4373f3ceeb419263d63109408b86f398564c9536

Authored by pbrook
1 parent b0109805

ARM TCG conversion 10/16.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4147 c046a42c-6fe2-441c-8c8c-71466251a162
target-arm/cpu.h
@@ -168,9 +168,6 @@ typedef struct CPUARMState { @@ -168,9 +168,6 @@ typedef struct CPUARMState {
168 int vec_len; 168 int vec_len;
169 int vec_stride; 169 int vec_stride;
170 170
171 - /* Temporary variables if we don't have spare fp regs. */  
172 - float32 tmp0s, tmp1s;  
173 - float64 tmp0d, tmp1d;  
174 /* scratch space when Tn are not sufficient. */ 171 /* scratch space when Tn are not sufficient. */
175 uint32_t scratch[8]; 172 uint32_t scratch[8];
176 173
target-arm/exec.h
@@ -25,13 +25,6 @@ register uint32_t T0 asm(AREG1); @@ -25,13 +25,6 @@ register uint32_t T0 asm(AREG1);
25 register uint32_t T1 asm(AREG2); 25 register uint32_t T1 asm(AREG2);
26 register uint32_t T2 asm(AREG3); 26 register uint32_t T2 asm(AREG3);
27 27
28 -/* TODO: Put these in FP regs on targets that have such things. */  
29 -/* It is ok for FT0s and FT0d to overlap. Likewise FT1s and FT1d. */  
30 -#define FT0s env->vfp.tmp0s  
31 -#define FT1s env->vfp.tmp1s  
32 -#define FT0d env->vfp.tmp0d  
33 -#define FT1d env->vfp.tmp1d  
34 -  
35 #define M0 env->iwmmxt.val 28 #define M0 env->iwmmxt.val
36 29
37 #include "cpu.h" 30 #include "cpu.h"
@@ -83,23 +76,5 @@ void cpu_loop_exit(void); @@ -83,23 +76,5 @@ void cpu_loop_exit(void);
83 76
84 void raise_exception(int); 77 void raise_exception(int);
85 78
86 -void do_vfp_abss(void);  
87 -void do_vfp_absd(void);  
88 -void do_vfp_negs(void);  
89 -void do_vfp_negd(void);  
90 -void do_vfp_sqrts(void);  
91 -void do_vfp_sqrtd(void);  
92 -void do_vfp_cmps(void);  
93 -void do_vfp_cmpd(void);  
94 -void do_vfp_cmpes(void);  
95 -void do_vfp_cmped(void);  
96 -void do_vfp_set_fpscr(void);  
97 -void do_vfp_get_fpscr(void);  
98 -float32 helper_recps_f32(float32, float32);  
99 -float32 helper_rsqrts_f32(float32, float32);  
100 -uint32_t helper_recpe_u32(uint32_t);  
101 -uint32_t helper_rsqrte_u32(uint32_t);  
102 -float32 helper_recpe_f32(float32);  
103 -float32 helper_rsqrte_f32(float32);  
104 void helper_neon_tbl(int rn, int maxindex); 79 void helper_neon_tbl(int rn, int maxindex);
105 uint32_t helper_neon_mul_p8(uint32_t op1, uint32_t op2); 80 uint32_t helper_neon_mul_p8(uint32_t op1, uint32_t op2);
target-arm/helper.c
@@ -2167,3 +2167,366 @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b) @@ -2167,3 +2167,366 @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
2167 return (a & mask) | (b & ~mask); 2167 return (a & mask) | (b & ~mask);
2168 } 2168 }
2169 2169
  2170 +
  2171 +/* VFP support. We follow the convention used for VFP instrunctions:
  2172 + Single precition routines have a "s" suffix, double precision a
  2173 + "d" suffix. */
  2174 +
  2175 +/* Convert host exception flags to vfp form. */
  2176 +static inline int vfp_exceptbits_from_host(int host_bits)
  2177 +{
  2178 + int target_bits = 0;
  2179 +
  2180 + if (host_bits & float_flag_invalid)
  2181 + target_bits |= 1;
  2182 + if (host_bits & float_flag_divbyzero)
  2183 + target_bits |= 2;
  2184 + if (host_bits & float_flag_overflow)
  2185 + target_bits |= 4;
  2186 + if (host_bits & float_flag_underflow)
  2187 + target_bits |= 8;
  2188 + if (host_bits & float_flag_inexact)
  2189 + target_bits |= 0x10;
  2190 + return target_bits;
  2191 +}
  2192 +
  2193 +uint32_t HELPER(vfp_get_fpscr)(CPUState *env)
  2194 +{
  2195 + int i;
  2196 + uint32_t fpscr;
  2197 +
  2198 + fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
  2199 + | (env->vfp.vec_len << 16)
  2200 + | (env->vfp.vec_stride << 20);
  2201 + i = get_float_exception_flags(&env->vfp.fp_status);
  2202 + fpscr |= vfp_exceptbits_from_host(i);
  2203 + return fpscr;
  2204 +}
  2205 +
  2206 +/* Convert vfp exception flags to target form. */
  2207 +static inline int vfp_exceptbits_to_host(int target_bits)
  2208 +{
  2209 + int host_bits = 0;
  2210 +
  2211 + if (target_bits & 1)
  2212 + host_bits |= float_flag_invalid;
  2213 + if (target_bits & 2)
  2214 + host_bits |= float_flag_divbyzero;
  2215 + if (target_bits & 4)
  2216 + host_bits |= float_flag_overflow;
  2217 + if (target_bits & 8)
  2218 + host_bits |= float_flag_underflow;
  2219 + if (target_bits & 0x10)
  2220 + host_bits |= float_flag_inexact;
  2221 + return host_bits;
  2222 +}
  2223 +
  2224 +void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
  2225 +{
  2226 + int i;
  2227 + uint32_t changed;
  2228 +
  2229 + changed = env->vfp.xregs[ARM_VFP_FPSCR];
  2230 + env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
  2231 + env->vfp.vec_len = (val >> 16) & 7;
  2232 + env->vfp.vec_stride = (val >> 20) & 3;
  2233 +
  2234 + changed ^= val;
  2235 + if (changed & (3 << 22)) {
  2236 + i = (val >> 22) & 3;
  2237 + switch (i) {
  2238 + case 0:
  2239 + i = float_round_nearest_even;
  2240 + break;
  2241 + case 1:
  2242 + i = float_round_up;
  2243 + break;
  2244 + case 2:
  2245 + i = float_round_down;
  2246 + break;
  2247 + case 3:
  2248 + i = float_round_to_zero;
  2249 + break;
  2250 + }
  2251 + set_float_rounding_mode(i, &env->vfp.fp_status);
  2252 + }
  2253 +
  2254 + i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
  2255 + set_float_exception_flags(i, &env->vfp.fp_status);
  2256 + /* XXX: FZ and DN are not implemented. */
  2257 +}
  2258 +
  2259 +#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
  2260 +
  2261 +#define VFP_BINOP(name) \
  2262 +float32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \
  2263 +{ \
  2264 + return float32_ ## name (a, b, &env->vfp.fp_status); \
  2265 +} \
  2266 +float64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \
  2267 +{ \
  2268 + return float64_ ## name (a, b, &env->vfp.fp_status); \
  2269 +}
  2270 +VFP_BINOP(add)
  2271 +VFP_BINOP(sub)
  2272 +VFP_BINOP(mul)
  2273 +VFP_BINOP(div)
  2274 +#undef VFP_BINOP
  2275 +
  2276 +float32 VFP_HELPER(neg, s)(float32 a)
  2277 +{
  2278 + return float32_chs(a);
  2279 +}
  2280 +
  2281 +float64 VFP_HELPER(neg, d)(float64 a)
  2282 +{
  2283 + return float32_chs(a);
  2284 +}
  2285 +
  2286 +float32 VFP_HELPER(abs, s)(float32 a)
  2287 +{
  2288 + return float32_abs(a);
  2289 +}
  2290 +
  2291 +float64 VFP_HELPER(abs, d)(float64 a)
  2292 +{
  2293 + return float32_abs(a);
  2294 +}
  2295 +
  2296 +float32 VFP_HELPER(sqrt, s)(float32 a, CPUState *env)
  2297 +{
  2298 + return float32_sqrt(a, &env->vfp.fp_status);
  2299 +}
  2300 +
  2301 +float64 VFP_HELPER(sqrt, d)(float64 a, CPUState *env)
  2302 +{
  2303 + return float64_sqrt(a, &env->vfp.fp_status);
  2304 +}
  2305 +
  2306 +/* XXX: check quiet/signaling case */
  2307 +#define DO_VFP_cmp(p, type) \
  2308 +void VFP_HELPER(cmp, p)(type a, type b, CPUState *env) \
  2309 +{ \
  2310 + uint32_t flags; \
  2311 + switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
  2312 + case 0: flags = 0x6; break; \
  2313 + case -1: flags = 0x8; break; \
  2314 + case 1: flags = 0x2; break; \
  2315 + default: case 2: flags = 0x3; break; \
  2316 + } \
  2317 + env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
  2318 + | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
  2319 +} \
  2320 +void VFP_HELPER(cmpe, p)(type a, type b, CPUState *env) \
  2321 +{ \
  2322 + uint32_t flags; \
  2323 + switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
  2324 + case 0: flags = 0x6; break; \
  2325 + case -1: flags = 0x8; break; \
  2326 + case 1: flags = 0x2; break; \
  2327 + default: case 2: flags = 0x3; break; \
  2328 + } \
  2329 + env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
  2330 + | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
  2331 +}
  2332 +DO_VFP_cmp(s, float32)
  2333 +DO_VFP_cmp(d, float64)
  2334 +#undef DO_VFP_cmp
  2335 +
  2336 +/* Helper routines to perform bitwise copies between float and int. */
  2337 +static inline float32 vfp_itos(uint32_t i)
  2338 +{
  2339 + union {
  2340 + uint32_t i;
  2341 + float32 s;
  2342 + } v;
  2343 +
  2344 + v.i = i;
  2345 + return v.s;
  2346 +}
  2347 +
  2348 +static inline uint32_t vfp_stoi(float32 s)
  2349 +{
  2350 + union {
  2351 + uint32_t i;
  2352 + float32 s;
  2353 + } v;
  2354 +
  2355 + v.s = s;
  2356 + return v.i;
  2357 +}
  2358 +
  2359 +static inline float64 vfp_itod(uint64_t i)
  2360 +{
  2361 + union {
  2362 + uint64_t i;
  2363 + float64 d;
  2364 + } v;
  2365 +
  2366 + v.i = i;
  2367 + return v.d;
  2368 +}
  2369 +
  2370 +static inline uint64_t vfp_dtoi(float64 d)
  2371 +{
  2372 + union {
  2373 + uint64_t i;
  2374 + float64 d;
  2375 + } v;
  2376 +
  2377 + v.d = d;
  2378 + return v.i;
  2379 +}
  2380 +
  2381 +/* Integer to float conversion. */
  2382 +float32 VFP_HELPER(uito, s)(float32 x, CPUState *env)
  2383 +{
  2384 + return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
  2385 +}
  2386 +
  2387 +float64 VFP_HELPER(uito, d)(float32 x, CPUState *env)
  2388 +{
  2389 + return uint32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
  2390 +}
  2391 +
  2392 +float32 VFP_HELPER(sito, s)(float32 x, CPUState *env)
  2393 +{
  2394 + return int32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
  2395 +}
  2396 +
  2397 +float64 VFP_HELPER(sito, d)(float32 x, CPUState *env)
  2398 +{
  2399 + return int32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
  2400 +}
  2401 +
  2402 +/* Float to integer conversion. */
  2403 +float32 VFP_HELPER(toui, s)(float32 x, CPUState *env)
  2404 +{
  2405 + return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status));
  2406 +}
  2407 +
  2408 +float32 VFP_HELPER(toui, d)(float64 x, CPUState *env)
  2409 +{
  2410 + return vfp_itos(float64_to_uint32(x, &env->vfp.fp_status));
  2411 +}
  2412 +
  2413 +float32 VFP_HELPER(tosi, s)(float32 x, CPUState *env)
  2414 +{
  2415 + return vfp_itos(float32_to_int32(x, &env->vfp.fp_status));
  2416 +}
  2417 +
  2418 +float32 VFP_HELPER(tosi, d)(float64 x, CPUState *env)
  2419 +{
  2420 + return vfp_itos(float64_to_int32(x, &env->vfp.fp_status));
  2421 +}
  2422 +
  2423 +float32 VFP_HELPER(touiz, s)(float32 x, CPUState *env)
  2424 +{
  2425 + return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status));
  2426 +}
  2427 +
  2428 +float32 VFP_HELPER(touiz, d)(float64 x, CPUState *env)
  2429 +{
  2430 + return vfp_itos(float64_to_uint32_round_to_zero(x, &env->vfp.fp_status));
  2431 +}
  2432 +
  2433 +float32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
  2434 +{
  2435 + return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status));
  2436 +}
  2437 +
  2438 +float32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
  2439 +{
  2440 + return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status));
  2441 +}
  2442 +
  2443 +/* floating point conversion */
  2444 +float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env)
  2445 +{
  2446 + return float32_to_float64(x, &env->vfp.fp_status);
  2447 +}
  2448 +
  2449 +float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env)
  2450 +{
  2451 + return float64_to_float32(x, &env->vfp.fp_status);
  2452 +}
  2453 +
  2454 +/* VFP3 fixed point conversion. */
  2455 +#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
  2456 +ftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \
  2457 +{ \
  2458 + ftype tmp; \
  2459 + tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(x), \
  2460 + &env->vfp.fp_status); \
  2461 + return ftype##_scalbn(tmp, shift, &env->vfp.fp_status); \
  2462 +} \
  2463 +ftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \
  2464 +{ \
  2465 + ftype tmp; \
  2466 + tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \
  2467 + return vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
  2468 + &env->vfp.fp_status)); \
  2469 +}
  2470 +
  2471 +VFP_CONV_FIX(sh, d, float64, int16, )
  2472 +VFP_CONV_FIX(sl, d, float64, int32, )
  2473 +VFP_CONV_FIX(uh, d, float64, uint16, u)
  2474 +VFP_CONV_FIX(ul, d, float64, uint32, u)
  2475 +VFP_CONV_FIX(sh, s, float32, int16, )
  2476 +VFP_CONV_FIX(sl, s, float32, int32, )
  2477 +VFP_CONV_FIX(uh, s, float32, uint16, u)
  2478 +VFP_CONV_FIX(ul, s, float32, uint32, u)
  2479 +#undef VFP_CONV_FIX
  2480 +
  2481 +float32 HELPER(recps_f32)(float32 a, float32 b, CPUState *env)
  2482 +{
  2483 + float_status *s = &env->vfp.fp_status;
  2484 + float32 two = int32_to_float32(2, s);
  2485 + return float32_sub(two, float32_mul(a, b, s), s);
  2486 +}
  2487 +
  2488 +float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env)
  2489 +{
  2490 + float_status *s = &env->vfp.fp_status;
  2491 + float32 three = int32_to_float32(3, s);
  2492 + return float32_sub(three, float32_mul(a, b, s), s);
  2493 +}
  2494 +
  2495 +/* TODO: The architecture specifies the value that the estimate functions
  2496 + should return. We return the exact reciprocal/root instead. */
  2497 +float32 HELPER(recpe_f32)(float32 a, CPUState *env)
  2498 +{
  2499 + float_status *s = &env->vfp.fp_status;
  2500 + float32 one = int32_to_float32(1, s);
  2501 + return float32_div(one, a, s);
  2502 +}
  2503 +
  2504 +float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
  2505 +{
  2506 + float_status *s = &env->vfp.fp_status;
  2507 + float32 one = int32_to_float32(1, s);
  2508 + return float32_div(one, float32_sqrt(a, s), s);
  2509 +}
  2510 +
  2511 +uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
  2512 +{
  2513 + float_status *s = &env->vfp.fp_status;
  2514 + float32 tmp;
  2515 + tmp = int32_to_float32(a, s);
  2516 + tmp = float32_scalbn(tmp, -32, s);
  2517 + tmp = helper_recpe_f32(tmp, env);
  2518 + tmp = float32_scalbn(tmp, 31, s);
  2519 + return float32_to_int32(tmp, s);
  2520 +}
  2521 +
  2522 +uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
  2523 +{
  2524 + float_status *s = &env->vfp.fp_status;
  2525 + float32 tmp;
  2526 + tmp = int32_to_float32(a, s);
  2527 + tmp = float32_scalbn(tmp, -32, s);
  2528 + tmp = helper_rsqrte_f32(tmp, env);
  2529 + tmp = float32_scalbn(tmp, 31, s);
  2530 + return float32_to_int32(tmp, s);
  2531 +}
  2532 +
target-arm/helpers.h
@@ -122,6 +122,69 @@ DEF_HELPER_0_3(set_r13_banked, void, (CPUState *, uint32_t, uint32_t)) @@ -122,6 +122,69 @@ DEF_HELPER_0_3(set_r13_banked, void, (CPUState *, uint32_t, uint32_t))
122 DEF_HELPER_1_1(get_user_reg, uint32_t, (uint32_t)) 122 DEF_HELPER_1_1(get_user_reg, uint32_t, (uint32_t))
123 DEF_HELPER_0_2(set_user_reg, void, (uint32_t, uint32_t)) 123 DEF_HELPER_0_2(set_user_reg, void, (uint32_t, uint32_t))
124 124
  125 +DEF_HELPER_1_1(vfp_get_fpscr, uint32_t, (CPUState *))
  126 +DEF_HELPER_0_2(vfp_set_fpscr, void, (CPUState *, uint32_t))
  127 +
  128 +DEF_HELPER_1_3(vfp_adds, float32, (float32, float32, CPUState *))
  129 +DEF_HELPER_1_3(vfp_addd, float64, (float64, float64, CPUState *))
  130 +DEF_HELPER_1_3(vfp_subs, float32, (float32, float32, CPUState *))
  131 +DEF_HELPER_1_3(vfp_subd, float64, (float64, float64, CPUState *))
  132 +DEF_HELPER_1_3(vfp_muls, float32, (float32, float32, CPUState *))
  133 +DEF_HELPER_1_3(vfp_muld, float64, (float64, float64, CPUState *))
  134 +DEF_HELPER_1_3(vfp_divs, float32, (float32, float32, CPUState *))
  135 +DEF_HELPER_1_3(vfp_divd, float64, (float64, float64, CPUState *))
  136 +DEF_HELPER_1_1(vfp_negs, float32, (float32))
  137 +DEF_HELPER_1_1(vfp_negd, float64, (float64))
  138 +DEF_HELPER_1_1(vfp_abss, float32, (float32))
  139 +DEF_HELPER_1_1(vfp_absd, float64, (float64))
  140 +DEF_HELPER_1_2(vfp_sqrts, float32, (float32, CPUState *))
  141 +DEF_HELPER_1_2(vfp_sqrtd, float64, (float64, CPUState *))
  142 +DEF_HELPER_0_3(vfp_cmps, void, (float32, float32, CPUState *))
  143 +DEF_HELPER_0_3(vfp_cmpd, void, (float64, float64, CPUState *))
  144 +DEF_HELPER_0_3(vfp_cmpes, void, (float32, float32, CPUState *))
  145 +DEF_HELPER_0_3(vfp_cmped, void, (float64, float64, CPUState *))
  146 +
  147 +DEF_HELPER_1_2(vfp_fcvtds, float64, (float32, CPUState *))
  148 +DEF_HELPER_1_2(vfp_fcvtsd, float32, (float64, CPUState *))
  149 +
  150 +DEF_HELPER_1_2(vfp_uitos, float32, (float32, CPUState *))
  151 +DEF_HELPER_1_2(vfp_uitod, float64, (float32, CPUState *))
  152 +DEF_HELPER_1_2(vfp_sitos, float32, (float32, CPUState *))
  153 +DEF_HELPER_1_2(vfp_sitod, float64, (float32, CPUState *))
  154 +
  155 +DEF_HELPER_1_2(vfp_touis, float32, (float32, CPUState *))
  156 +DEF_HELPER_1_2(vfp_touid, float32, (float64, CPUState *))
  157 +DEF_HELPER_1_2(vfp_touizs, float32, (float32, CPUState *))
  158 +DEF_HELPER_1_2(vfp_touizd, float32, (float64, CPUState *))
  159 +DEF_HELPER_1_2(vfp_tosis, float32, (float32, CPUState *))
  160 +DEF_HELPER_1_2(vfp_tosid, float32, (float64, CPUState *))
  161 +DEF_HELPER_1_2(vfp_tosizs, float32, (float32, CPUState *))
  162 +DEF_HELPER_1_2(vfp_tosizd, float32, (float64, CPUState *))
  163 +
  164 +DEF_HELPER_1_3(vfp_toshs, float32, (float32, uint32_t, CPUState *))
  165 +DEF_HELPER_1_3(vfp_tosls, float32, (float32, uint32_t, CPUState *))
  166 +DEF_HELPER_1_3(vfp_touhs, float32, (float32, uint32_t, CPUState *))
  167 +DEF_HELPER_1_3(vfp_touls, float32, (float32, uint32_t, CPUState *))
  168 +DEF_HELPER_1_3(vfp_toshd, float64, (float64, uint32_t, CPUState *))
  169 +DEF_HELPER_1_3(vfp_tosld, float64, (float64, uint32_t, CPUState *))
  170 +DEF_HELPER_1_3(vfp_touhd, float64, (float64, uint32_t, CPUState *))
  171 +DEF_HELPER_1_3(vfp_tould, float64, (float64, uint32_t, CPUState *))
  172 +DEF_HELPER_1_3(vfp_shtos, float32, (float32, uint32_t, CPUState *))
  173 +DEF_HELPER_1_3(vfp_sltos, float32, (float32, uint32_t, CPUState *))
  174 +DEF_HELPER_1_3(vfp_uhtos, float32, (float32, uint32_t, CPUState *))
  175 +DEF_HELPER_1_3(vfp_ultos, float32, (float32, uint32_t, CPUState *))
  176 +DEF_HELPER_1_3(vfp_shtod, float64, (float64, uint32_t, CPUState *))
  177 +DEF_HELPER_1_3(vfp_sltod, float64, (float64, uint32_t, CPUState *))
  178 +DEF_HELPER_1_3(vfp_uhtod, float64, (float64, uint32_t, CPUState *))
  179 +DEF_HELPER_1_3(vfp_ultod, float64, (float64, uint32_t, CPUState *))
  180 +
  181 +DEF_HELPER_1_3(recps_f32, float32, (float32, float32, CPUState *))
  182 +DEF_HELPER_1_3(rsqrts_f32, float32, (float32, float32, CPUState *))
  183 +DEF_HELPER_1_2(recpe_f32, float32, (float32, CPUState *))
  184 +DEF_HELPER_1_2(rsqrte_f32, float32, (float32, CPUState *))
  185 +DEF_HELPER_1_2(recpe_u32, uint32_t, (uint32_t, CPUState *))
  186 +DEF_HELPER_1_2(rsqrte_u32, uint32_t, (uint32_t, CPUState *))
  187 +
125 #undef DEF_HELPER 188 #undef DEF_HELPER
126 #undef DEF_HELPER_0_0 189 #undef DEF_HELPER_0_0
127 #undef DEF_HELPER_0_1 190 #undef DEF_HELPER_0_1
target-arm/op.c
@@ -252,319 +252,6 @@ void OPPROTO op_rorl_T1_T0_cc(void) @@ -252,319 +252,6 @@ void OPPROTO op_rorl_T1_T0_cc(void)
252 FORCE_RET(); 252 FORCE_RET();
253 } 253 }
254 254
255 -/* VFP support. We follow the convention used for VFP instrunctions:  
256 - Single precition routines have a "s" suffix, double precision a  
257 - "d" suffix. */  
258 -  
259 -#define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void)  
260 -  
261 -#define VFP_BINOP(name) \  
262 -VFP_OP(name, s) \  
263 -{ \  
264 - FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status); \  
265 -} \  
266 -VFP_OP(name, d) \  
267 -{ \  
268 - FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status); \  
269 -}  
270 -VFP_BINOP(add)  
271 -VFP_BINOP(sub)  
272 -VFP_BINOP(mul)  
273 -VFP_BINOP(div)  
274 -#undef VFP_BINOP  
275 -  
276 -#define VFP_HELPER(name) \  
277 -VFP_OP(name, s) \  
278 -{ \  
279 - do_vfp_##name##s(); \  
280 -} \  
281 -VFP_OP(name, d) \  
282 -{ \  
283 - do_vfp_##name##d(); \  
284 -}  
285 -VFP_HELPER(abs)  
286 -VFP_HELPER(sqrt)  
287 -VFP_HELPER(cmp)  
288 -VFP_HELPER(cmpe)  
289 -#undef VFP_HELPER  
290 -  
291 -/* XXX: Will this do the right thing for NANs. Should invert the signbit  
292 - without looking at the rest of the value. */  
293 -VFP_OP(neg, s)  
294 -{  
295 - FT0s = float32_chs(FT0s);  
296 -}  
297 -  
298 -VFP_OP(neg, d)  
299 -{  
300 - FT0d = float64_chs(FT0d);  
301 -}  
302 -  
303 -VFP_OP(F1_ld0, s)  
304 -{  
305 - union {  
306 - uint32_t i;  
307 - float32 s;  
308 - } v;  
309 - v.i = 0;  
310 - FT1s = v.s;  
311 -}  
312 -  
313 -VFP_OP(F1_ld0, d)  
314 -{  
315 - union {  
316 - uint64_t i;  
317 - float64 d;  
318 - } v;  
319 - v.i = 0;  
320 - FT1d = v.d;  
321 -}  
322 -  
323 -/* Helper routines to perform bitwise copies between float and int. */  
324 -static inline float32 vfp_itos(uint32_t i)  
325 -{  
326 - union {  
327 - uint32_t i;  
328 - float32 s;  
329 - } v;  
330 -  
331 - v.i = i;  
332 - return v.s;  
333 -}  
334 -  
335 -static inline uint32_t vfp_stoi(float32 s)  
336 -{  
337 - union {  
338 - uint32_t i;  
339 - float32 s;  
340 - } v;  
341 -  
342 - v.s = s;  
343 - return v.i;  
344 -}  
345 -  
346 -static inline float64 vfp_itod(uint64_t i)  
347 -{  
348 - union {  
349 - uint64_t i;  
350 - float64 d;  
351 - } v;  
352 -  
353 - v.i = i;  
354 - return v.d;  
355 -}  
356 -  
357 -static inline uint64_t vfp_dtoi(float64 d)  
358 -{  
359 - union {  
360 - uint64_t i;  
361 - float64 d;  
362 - } v;  
363 -  
364 - v.d = d;  
365 - return v.i;  
366 -}  
367 -  
368 -/* Integer to float conversion. */  
369 -VFP_OP(uito, s)  
370 -{  
371 - FT0s = uint32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);  
372 -}  
373 -  
374 -VFP_OP(uito, d)  
375 -{  
376 - FT0d = uint32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);  
377 -}  
378 -  
379 -VFP_OP(sito, s)  
380 -{  
381 - FT0s = int32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);  
382 -}  
383 -  
384 -VFP_OP(sito, d)  
385 -{  
386 - FT0d = int32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);  
387 -}  
388 -  
389 -/* Float to integer conversion. */  
390 -VFP_OP(toui, s)  
391 -{  
392 - FT0s = vfp_itos(float32_to_uint32(FT0s, &env->vfp.fp_status));  
393 -}  
394 -  
395 -VFP_OP(toui, d)  
396 -{  
397 - FT0s = vfp_itos(float64_to_uint32(FT0d, &env->vfp.fp_status));  
398 -}  
399 -  
400 -VFP_OP(tosi, s)  
401 -{  
402 - FT0s = vfp_itos(float32_to_int32(FT0s, &env->vfp.fp_status));  
403 -}  
404 -  
405 -VFP_OP(tosi, d)  
406 -{  
407 - FT0s = vfp_itos(float64_to_int32(FT0d, &env->vfp.fp_status));  
408 -}  
409 -  
410 -/* TODO: Set rounding mode properly. */  
411 -VFP_OP(touiz, s)  
412 -{  
413 - FT0s = vfp_itos(float32_to_uint32_round_to_zero(FT0s, &env->vfp.fp_status));  
414 -}  
415 -  
416 -VFP_OP(touiz, d)  
417 -{  
418 - FT0s = vfp_itos(float64_to_uint32_round_to_zero(FT0d, &env->vfp.fp_status));  
419 -}  
420 -  
421 -VFP_OP(tosiz, s)  
422 -{  
423 - FT0s = vfp_itos(float32_to_int32_round_to_zero(FT0s, &env->vfp.fp_status));  
424 -}  
425 -  
426 -VFP_OP(tosiz, d)  
427 -{  
428 - FT0s = vfp_itos(float64_to_int32_round_to_zero(FT0d, &env->vfp.fp_status));  
429 -}  
430 -  
431 -/* floating point conversion */  
432 -VFP_OP(fcvtd, s)  
433 -{  
434 - FT0d = float32_to_float64(FT0s, &env->vfp.fp_status);  
435 -}  
436 -  
437 -VFP_OP(fcvts, d)  
438 -{  
439 - FT0s = float64_to_float32(FT0d, &env->vfp.fp_status);  
440 -}  
441 -  
442 -/* VFP3 fixed point conversion. */  
443 -#define VFP_CONV_FIX(name, p, ftype, itype, sign) \  
444 -VFP_OP(name##to, p) \  
445 -{ \  
446 - ftype tmp; \  
447 - tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(FT0##p), \  
448 - &env->vfp.fp_status); \  
449 - FT0##p = ftype##_scalbn(tmp, PARAM1, &env->vfp.fp_status); \  
450 -} \  
451 -VFP_OP(to##name, p) \  
452 -{ \  
453 - ftype tmp; \  
454 - tmp = ftype##_scalbn(FT0##p, PARAM1, &env->vfp.fp_status); \  
455 - FT0##p = vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \  
456 - &env->vfp.fp_status)); \  
457 -}  
458 -  
459 -VFP_CONV_FIX(sh, d, float64, int16, )  
460 -VFP_CONV_FIX(sl, d, float64, int32, )  
461 -VFP_CONV_FIX(uh, d, float64, uint16, u)  
462 -VFP_CONV_FIX(ul, d, float64, uint32, u)  
463 -VFP_CONV_FIX(sh, s, float32, int16, )  
464 -VFP_CONV_FIX(sl, s, float32, int32, )  
465 -VFP_CONV_FIX(uh, s, float32, uint16, u)  
466 -VFP_CONV_FIX(ul, s, float32, uint32, u)  
467 -  
468 -/* Get and Put values from registers. */  
469 -VFP_OP(getreg_F0, d)  
470 -{  
471 - FT0d = *(float64 *)((char *) env + PARAM1);  
472 -}  
473 -  
474 -VFP_OP(getreg_F0, s)  
475 -{  
476 - FT0s = *(float32 *)((char *) env + PARAM1);  
477 -}  
478 -  
479 -VFP_OP(getreg_F1, d)  
480 -{  
481 - FT1d = *(float64 *)((char *) env + PARAM1);  
482 -}  
483 -  
484 -VFP_OP(getreg_F1, s)  
485 -{  
486 - FT1s = *(float32 *)((char *) env + PARAM1);  
487 -}  
488 -  
489 -VFP_OP(setreg_F0, d)  
490 -{  
491 - *(float64 *)((char *) env + PARAM1) = FT0d;  
492 -}  
493 -  
494 -VFP_OP(setreg_F0, s)  
495 -{  
496 - *(float32 *)((char *) env + PARAM1) = FT0s;  
497 -}  
498 -  
499 -void OPPROTO op_vfp_movl_T0_fpscr(void)  
500 -{  
501 - do_vfp_get_fpscr ();  
502 -}  
503 -  
504 -void OPPROTO op_vfp_movl_T0_fpscr_flags(void)  
505 -{  
506 - T0 = env->vfp.xregs[ARM_VFP_FPSCR] & (0xf << 28);  
507 -}  
508 -  
509 -void OPPROTO op_vfp_movl_fpscr_T0(void)  
510 -{  
511 - do_vfp_set_fpscr();  
512 -}  
513 -  
514 -void OPPROTO op_vfp_movl_T0_xreg(void)  
515 -{  
516 - T0 = env->vfp.xregs[PARAM1];  
517 -}  
518 -  
519 -void OPPROTO op_vfp_movl_xreg_T0(void)  
520 -{  
521 - env->vfp.xregs[PARAM1] = T0;  
522 -}  
523 -  
524 -/* Move between FT0s to T0 */  
525 -void OPPROTO op_vfp_mrs(void)  
526 -{  
527 - T0 = vfp_stoi(FT0s);  
528 -}  
529 -  
530 -void OPPROTO op_vfp_msr(void)  
531 -{  
532 - FT0s = vfp_itos(T0);  
533 -}  
534 -  
535 -/* Move between FT0d and {T0,T1} */  
536 -void OPPROTO op_vfp_mrrd(void)  
537 -{  
538 - CPU_DoubleU u;  
539 -  
540 - u.d = FT0d;  
541 - T0 = u.l.lower;  
542 - T1 = u.l.upper;  
543 -}  
544 -  
545 -void OPPROTO op_vfp_mdrr(void)  
546 -{  
547 - CPU_DoubleU u;  
548 -  
549 - u.l.lower = T0;  
550 - u.l.upper = T1;  
551 - FT0d = u.d;  
552 -}  
553 -  
554 -/* Load immediate. PARAM1 is the 32 most significant bits of the value. */  
555 -void OPPROTO op_vfp_fconstd(void)  
556 -{  
557 - CPU_DoubleU u;  
558 - u.l.upper = PARAM1;  
559 - u.l.lower = 0;  
560 - FT0d = u.d;  
561 -}  
562 -  
563 -void OPPROTO op_vfp_fconsts(void)  
564 -{  
565 - FT0s = vfp_itos(PARAM1);  
566 -}  
567 -  
568 void OPPROTO op_movl_cp_T0(void) 255 void OPPROTO op_movl_cp_T0(void)
569 { 256 {
570 helper_set_cp(env, PARAM1, T0); 257 helper_set_cp(env, PARAM1, T0);
target-arm/op_helper.c
@@ -40,194 +40,6 @@ void cpu_unlock(void) @@ -40,194 +40,6 @@ void cpu_unlock(void)
40 spin_unlock(&global_cpu_lock); 40 spin_unlock(&global_cpu_lock);
41 } 41 }
42 42
43 -/* VFP support. */  
44 -  
45 -void do_vfp_abss(void)  
46 -{  
47 - FT0s = float32_abs(FT0s);  
48 -}  
49 -  
50 -void do_vfp_absd(void)  
51 -{  
52 - FT0d = float64_abs(FT0d);  
53 -}  
54 -  
55 -void do_vfp_sqrts(void)  
56 -{  
57 - FT0s = float32_sqrt(FT0s, &env->vfp.fp_status);  
58 -}  
59 -  
60 -void do_vfp_sqrtd(void)  
61 -{  
62 - FT0d = float64_sqrt(FT0d, &env->vfp.fp_status);  
63 -}  
64 -  
65 -/* XXX: check quiet/signaling case */  
66 -#define DO_VFP_cmp(p, size) \  
67 -void do_vfp_cmp##p(void) \  
68 -{ \  
69 - uint32_t flags; \  
70 - switch(float ## size ## _compare_quiet(FT0##p, FT1##p, &env->vfp.fp_status)) {\  
71 - case 0: flags = 0x6; break;\  
72 - case -1: flags = 0x8; break;\  
73 - case 1: flags = 0x2; break;\  
74 - default: case 2: flags = 0x3; break;\  
75 - }\  
76 - env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28)\  
77 - | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \  
78 - FORCE_RET(); \  
79 -}\  
80 -\  
81 -void do_vfp_cmpe##p(void) \  
82 -{ \  
83 - uint32_t flags; \  
84 - switch(float ## size ## _compare(FT0##p, FT1##p, &env->vfp.fp_status)) {\  
85 - case 0: flags = 0x6; break;\  
86 - case -1: flags = 0x8; break;\  
87 - case 1: flags = 0x2; break;\  
88 - default: case 2: flags = 0x3; break;\  
89 - }\  
90 - env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28)\  
91 - | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \  
92 - FORCE_RET(); \  
93 -}  
94 -DO_VFP_cmp(s, 32)  
95 -DO_VFP_cmp(d, 64)  
96 -#undef DO_VFP_cmp  
97 -  
98 -/* Convert host exception flags to vfp form. */  
99 -static inline int vfp_exceptbits_from_host(int host_bits)  
100 -{  
101 - int target_bits = 0;  
102 -  
103 - if (host_bits & float_flag_invalid)  
104 - target_bits |= 1;  
105 - if (host_bits & float_flag_divbyzero)  
106 - target_bits |= 2;  
107 - if (host_bits & float_flag_overflow)  
108 - target_bits |= 4;  
109 - if (host_bits & float_flag_underflow)  
110 - target_bits |= 8;  
111 - if (host_bits & float_flag_inexact)  
112 - target_bits |= 0x10;  
113 - return target_bits;  
114 -}  
115 -  
116 -/* Convert vfp exception flags to target form. */  
117 -static inline int vfp_exceptbits_to_host(int target_bits)  
118 -{  
119 - int host_bits = 0;  
120 -  
121 - if (target_bits & 1)  
122 - host_bits |= float_flag_invalid;  
123 - if (target_bits & 2)  
124 - host_bits |= float_flag_divbyzero;  
125 - if (target_bits & 4)  
126 - host_bits |= float_flag_overflow;  
127 - if (target_bits & 8)  
128 - host_bits |= float_flag_underflow;  
129 - if (target_bits & 0x10)  
130 - host_bits |= float_flag_inexact;  
131 - return host_bits;  
132 -}  
133 -  
134 -void do_vfp_set_fpscr(void)  
135 -{  
136 - int i;  
137 - uint32_t changed;  
138 -  
139 - changed = env->vfp.xregs[ARM_VFP_FPSCR];  
140 - env->vfp.xregs[ARM_VFP_FPSCR] = (T0 & 0xffc8ffff);  
141 - env->vfp.vec_len = (T0 >> 16) & 7;  
142 - env->vfp.vec_stride = (T0 >> 20) & 3;  
143 -  
144 - changed ^= T0;  
145 - if (changed & (3 << 22)) {  
146 - i = (T0 >> 22) & 3;  
147 - switch (i) {  
148 - case 0:  
149 - i = float_round_nearest_even;  
150 - break;  
151 - case 1:  
152 - i = float_round_up;  
153 - break;  
154 - case 2:  
155 - i = float_round_down;  
156 - break;  
157 - case 3:  
158 - i = float_round_to_zero;  
159 - break;  
160 - }  
161 - set_float_rounding_mode(i, &env->vfp.fp_status);  
162 - }  
163 -  
164 - i = vfp_exceptbits_to_host((T0 >> 8) & 0x1f);  
165 - set_float_exception_flags(i, &env->vfp.fp_status);  
166 - /* XXX: FZ and DN are not implemented. */  
167 -}  
168 -  
169 -void do_vfp_get_fpscr(void)  
170 -{  
171 - int i;  
172 -  
173 - T0 = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff) | (env->vfp.vec_len << 16)  
174 - | (env->vfp.vec_stride << 20);  
175 - i = get_float_exception_flags(&env->vfp.fp_status);  
176 - T0 |= vfp_exceptbits_from_host(i);  
177 -}  
178 -  
179 -float32 helper_recps_f32(float32 a, float32 b)  
180 -{  
181 - float_status *s = &env->vfp.fp_status;  
182 - float32 two = int32_to_float32(2, s);  
183 - return float32_sub(two, float32_mul(a, b, s), s);  
184 -}  
185 -  
186 -float32 helper_rsqrts_f32(float32 a, float32 b)  
187 -{  
188 - float_status *s = &env->vfp.fp_status;  
189 - float32 three = int32_to_float32(3, s);  
190 - return float32_sub(three, float32_mul(a, b, s), s);  
191 -}  
192 -  
193 -/* TODO: The architecture specifies the value that the estimate functions  
194 - should return. We return the exact reciprocal/root instead. */  
195 -float32 helper_recpe_f32(float32 a)  
196 -{  
197 - float_status *s = &env->vfp.fp_status;  
198 - float32 one = int32_to_float32(1, s);  
199 - return float32_div(one, a, s);  
200 -}  
201 -  
202 -float32 helper_rsqrte_f32(float32 a)  
203 -{  
204 - float_status *s = &env->vfp.fp_status;  
205 - float32 one = int32_to_float32(1, s);  
206 - return float32_div(one, float32_sqrt(a, s), s);  
207 -}  
208 -  
209 -uint32_t helper_recpe_u32(uint32_t a)  
210 -{  
211 - float_status *s = &env->vfp.fp_status;  
212 - float32 tmp;  
213 - tmp = int32_to_float32(a, s);  
214 - tmp = float32_scalbn(tmp, -32, s);  
215 - tmp = helper_recpe_f32(tmp);  
216 - tmp = float32_scalbn(tmp, 31, s);  
217 - return float32_to_int32(tmp, s);  
218 -}  
219 -  
220 -uint32_t helper_rsqrte_u32(uint32_t a)  
221 -{  
222 - float_status *s = &env->vfp.fp_status;  
223 - float32 tmp;  
224 - tmp = int32_to_float32(a, s);  
225 - tmp = float32_scalbn(tmp, -32, s);  
226 - tmp = helper_rsqrte_f32(tmp);  
227 - tmp = float32_scalbn(tmp, 31, s);  
228 - return float32_to_int32(tmp, s);  
229 -}  
230 -  
231 void helper_neon_tbl(int rn, int maxindex) 43 void helper_neon_tbl(int rn, int maxindex)
232 { 44 {
233 uint32_t val; 45 uint32_t val;
target-arm/op_mem.h
@@ -77,24 +77,6 @@ void OPPROTO glue(op_stqex,MEMSUFFIX)(void) @@ -77,24 +77,6 @@ void OPPROTO glue(op_stqex,MEMSUFFIX)(void)
77 FORCE_RET(); 77 FORCE_RET();
78 } 78 }
79 79
80 -/* Floating point load/store. Address is in T1 */  
81 -#define VFP_MEM_OP(p, w) \  
82 -void OPPROTO glue(op_vfp_ld##p,MEMSUFFIX)(void) \  
83 -{ \  
84 - FT0##p = glue(ldf##w,MEMSUFFIX)(T1); \  
85 - FORCE_RET(); \  
86 -} \  
87 -void OPPROTO glue(op_vfp_st##p,MEMSUFFIX)(void) \  
88 -{ \  
89 - glue(stf##w,MEMSUFFIX)(T1, FT0##p); \  
90 - FORCE_RET(); \  
91 -}  
92 -  
93 -VFP_MEM_OP(s,l)  
94 -VFP_MEM_OP(d,q)  
95 -  
96 -#undef VFP_MEM_OP  
97 -  
98 /* iwMMXt load/store. Address is in T1 */ 80 /* iwMMXt load/store. Address is in T1 */
99 #define MMX_MEM_OP(name, ldname) \ 81 #define MMX_MEM_OP(name, ldname) \
100 void OPPROTO glue(op_iwmmxt_ld##name,MEMSUFFIX)(void) \ 82 void OPPROTO glue(op_iwmmxt_ld##name,MEMSUFFIX)(void) \
target-arm/op_neon.h
@@ -14,6 +14,29 @@ @@ -14,6 +14,29 @@
14 #define NFS &env->vfp.fp_status 14 #define NFS &env->vfp.fp_status
15 #define NEON_OP(name) void OPPROTO op_neon_##name (void) 15 #define NEON_OP(name) void OPPROTO op_neon_##name (void)
16 16
  17 +/* Helper routines to perform bitwise copies between float and int. */
  18 +static inline float32 vfp_itos(uint32_t i)
  19 +{
  20 + union {
  21 + uint32_t i;
  22 + float32 s;
  23 + } v;
  24 +
  25 + v.i = i;
  26 + return v.s;
  27 +}
  28 +
  29 +static inline uint32_t vfp_stoi(float32 s)
  30 +{
  31 + union {
  32 + uint32_t i;
  33 + float32 s;
  34 + } v;
  35 +
  36 + v.s = s;
  37 + return v.i;
  38 +}
  39 +
17 NEON_OP(getreg_T0) 40 NEON_OP(getreg_T0)
18 { 41 {
19 T0 = *(uint32_t *)((char *) env + PARAM1); 42 T0 = *(uint32_t *)((char *) env + PARAM1);
@@ -754,18 +777,6 @@ NEON_VOP(qrdmulh_s32, neon_s32, 1) @@ -754,18 +777,6 @@ NEON_VOP(qrdmulh_s32, neon_s32, 1)
754 #undef NEON_FN 777 #undef NEON_FN
755 #undef NEON_QDMULH32 778 #undef NEON_QDMULH32
756 779
757 -NEON_OP(recps_f32)  
758 -{  
759 - T0 = vfp_stoi(helper_recps_f32(vfp_itos(T0), vfp_itos(T1)));  
760 - FORCE_RET();  
761 -}  
762 -  
763 -NEON_OP(rsqrts_f32)  
764 -{  
765 - T0 = vfp_stoi(helper_rsqrts_f32(vfp_itos(T0), vfp_itos(T1)));  
766 - FORCE_RET();  
767 -}  
768 -  
769 /* Floating point comparisons produce an integer result. */ 780 /* Floating point comparisons produce an integer result. */
770 #define NEON_VOP_FCMP(name, cmp) \ 781 #define NEON_VOP_FCMP(name, cmp) \
771 NEON_OP(name) \ 782 NEON_OP(name) \
@@ -1702,27 +1713,6 @@ NEON_OP(zip_u16) @@ -1702,27 +1713,6 @@ NEON_OP(zip_u16)
1702 FORCE_RET(); 1713 FORCE_RET();
1703 } 1714 }
1704 1715
1705 -/* Reciprocal/root estimate. */  
1706 -NEON_OP(recpe_u32)  
1707 -{  
1708 - T0 = helper_recpe_u32(T0);  
1709 -}  
1710 -  
1711 -NEON_OP(rsqrte_u32)  
1712 -{  
1713 - T0 = helper_rsqrte_u32(T0);  
1714 -}  
1715 -  
1716 -NEON_OP(recpe_f32)  
1717 -{  
1718 - FT0s = helper_recpe_f32(FT0s);  
1719 -}  
1720 -  
1721 -NEON_OP(rsqrte_f32)  
1722 -{  
1723 - FT0s = helper_rsqrte_f32(FT0s);  
1724 -}  
1725 -  
1726 /* Table lookup. This accessed the register file directly. */ 1716 /* Table lookup. This accessed the register file directly. */
1727 NEON_OP(tbl) 1717 NEON_OP(tbl)
1728 { 1718 {
target-arm/translate.c
@@ -79,6 +79,7 @@ extern int loglevel; @@ -79,6 +79,7 @@ extern int loglevel;
79 static TCGv cpu_env; 79 static TCGv cpu_env;
80 /* FIXME: These should be removed. */ 80 /* FIXME: These should be removed. */
81 static TCGv cpu_T[3]; 81 static TCGv cpu_T[3];
  82 +static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
82 83
83 /* initialize TCG globals. */ 84 /* initialize TCG globals. */
84 void arm_translate_init(void) 85 void arm_translate_init(void)
@@ -959,16 +960,16 @@ static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, @@ -959,16 +960,16 @@ static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
959 } 960 }
960 } 961 }
961 962
962 -#define VFP_OP(name) \  
963 -static inline void gen_vfp_##name(int dp) \  
964 -{ \  
965 - if (dp) \  
966 - gen_op_vfp_##name##d(); \  
967 - else \  
968 - gen_op_vfp_##name##s(); \ 963 +#define VFP_OP2(name) \
  964 +static inline void gen_vfp_##name(int dp) \
  965 +{ \
  966 + if (dp) \
  967 + gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
  968 + else \
  969 + gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
969 } 970 }
970 971
971 -#define VFP_OP1(name) \ 972 +#define VFP_OP1i(name) \
972 static inline void gen_vfp_##name(int dp, int arg) \ 973 static inline void gen_vfp_##name(int dp, int arg) \
973 { \ 974 { \
974 if (dp) \ 975 if (dp) \
@@ -977,55 +978,141 @@ static inline void gen_vfp_##name(int dp, int arg) \ @@ -977,55 +978,141 @@ static inline void gen_vfp_##name(int dp, int arg) \
977 gen_op_vfp_##name##s(arg); \ 978 gen_op_vfp_##name##s(arg); \
978 } 979 }
979 980
980 -VFP_OP(add)  
981 -VFP_OP(sub)  
982 -VFP_OP(mul)  
983 -VFP_OP(div)  
984 -VFP_OP(neg)  
985 -VFP_OP(abs)  
986 -VFP_OP(sqrt)  
987 -VFP_OP(cmp)  
988 -VFP_OP(cmpe)  
989 -VFP_OP(F1_ld0)  
990 -VFP_OP(uito)  
991 -VFP_OP(sito)  
992 -VFP_OP(toui)  
993 -VFP_OP(touiz)  
994 -VFP_OP(tosi)  
995 -VFP_OP(tosiz)  
996 -VFP_OP1(tosh)  
997 -VFP_OP1(tosl)  
998 -VFP_OP1(touh)  
999 -VFP_OP1(toul)  
1000 -VFP_OP1(shto)  
1001 -VFP_OP1(slto)  
1002 -VFP_OP1(uhto)  
1003 -VFP_OP1(ulto)  
1004 -  
1005 -#undef VFP_OP  
1006 -  
1007 -static inline void gen_vfp_fconst(int dp, uint32_t val) 981 +VFP_OP2(add)
  982 +VFP_OP2(sub)
  983 +VFP_OP2(mul)
  984 +VFP_OP2(div)
  985 +
  986 +#undef VFP_OP2
  987 +
  988 +static inline void gen_vfp_abs(int dp)
  989 +{
  990 + if (dp)
  991 + gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
  992 + else
  993 + gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
  994 +}
  995 +
  996 +static inline void gen_vfp_neg(int dp)
  997 +{
  998 + if (dp)
  999 + gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
  1000 + else
  1001 + gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
  1002 +}
  1003 +
  1004 +static inline void gen_vfp_sqrt(int dp)
  1005 +{
  1006 + if (dp)
  1007 + gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
  1008 + else
  1009 + gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
  1010 +}
  1011 +
  1012 +static inline void gen_vfp_cmp(int dp)
  1013 +{
  1014 + if (dp)
  1015 + gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
  1016 + else
  1017 + gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
  1018 +}
  1019 +
  1020 +static inline void gen_vfp_cmpe(int dp)
  1021 +{
  1022 + if (dp)
  1023 + gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
  1024 + else
  1025 + gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
  1026 +}
  1027 +
  1028 +static inline void gen_vfp_F1_ld0(int dp)
  1029 +{
  1030 + if (dp)
  1031 + tcg_gen_movi_i64(cpu_F0d, 0);
  1032 + else
  1033 + tcg_gen_movi_i32(cpu_F0s, 0);
  1034 +}
  1035 +
  1036 +static inline void gen_vfp_uito(int dp)
  1037 +{
  1038 + if (dp)
  1039 + gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
  1040 + else
  1041 + gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
  1042 +}
  1043 +
  1044 +static inline void gen_vfp_sito(int dp)
  1045 +{
  1046 + if (dp)
  1047 + gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
  1048 + else
  1049 + gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
  1050 +}
  1051 +
  1052 +static inline void gen_vfp_toui(int dp)
  1053 +{
  1054 + if (dp)
  1055 + gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
  1056 + else
  1057 + gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
  1058 +}
  1059 +
  1060 +static inline void gen_vfp_touiz(int dp)
  1061 +{
  1062 + if (dp)
  1063 + gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
  1064 + else
  1065 + gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
  1066 +}
  1067 +
  1068 +static inline void gen_vfp_tosi(int dp)
  1069 +{
  1070 + if (dp)
  1071 + gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
  1072 + else
  1073 + gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
  1074 +}
  1075 +
  1076 +static inline void gen_vfp_tosiz(int dp)
1008 { 1077 {
1009 if (dp) 1078 if (dp)
1010 - gen_op_vfp_fconstd(val); 1079 + gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1011 else 1080 else
1012 - gen_op_vfp_fconsts(val); 1081 + gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
  1082 +}
  1083 +
  1084 +#define VFP_GEN_FIX(name) \
  1085 +static inline void gen_vfp_##name(int dp, int shift) \
  1086 +{ \
  1087 + if (dp) \
  1088 + gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
  1089 + else \
  1090 + gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1013 } 1091 }
  1092 +VFP_GEN_FIX(tosh)
  1093 +VFP_GEN_FIX(tosl)
  1094 +VFP_GEN_FIX(touh)
  1095 +VFP_GEN_FIX(toul)
  1096 +VFP_GEN_FIX(shto)
  1097 +VFP_GEN_FIX(slto)
  1098 +VFP_GEN_FIX(uhto)
  1099 +VFP_GEN_FIX(ulto)
  1100 +#undef VFP_GEN_FIX
1014 1101
1015 static inline void gen_vfp_ld(DisasContext *s, int dp) 1102 static inline void gen_vfp_ld(DisasContext *s, int dp)
1016 { 1103 {
1017 if (dp) 1104 if (dp)
1018 - gen_ldst(vfp_ldd, s); 1105 + tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1019 else 1106 else
1020 - gen_ldst(vfp_lds, s); 1107 + tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1021 } 1108 }
1022 1109
1023 static inline void gen_vfp_st(DisasContext *s, int dp) 1110 static inline void gen_vfp_st(DisasContext *s, int dp)
1024 { 1111 {
1025 if (dp) 1112 if (dp)
1026 - gen_ldst(vfp_std, s); 1113 + tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1027 else 1114 else
1028 - gen_ldst(vfp_sts, s); 1115 + tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1029 } 1116 }
1030 1117
1031 static inline long 1118 static inline long
@@ -1055,28 +1142,33 @@ neon_reg_offset (int reg, int n) @@ -1055,28 +1142,33 @@ neon_reg_offset (int reg, int n)
1055 #define NEON_GET_REG(T, reg, n) gen_op_neon_getreg_##T(neon_reg_offset(reg, n)) 1142 #define NEON_GET_REG(T, reg, n) gen_op_neon_getreg_##T(neon_reg_offset(reg, n))
1056 #define NEON_SET_REG(T, reg, n) gen_op_neon_setreg_##T(neon_reg_offset(reg, n)) 1143 #define NEON_SET_REG(T, reg, n) gen_op_neon_setreg_##T(neon_reg_offset(reg, n))
1057 1144
  1145 +#define tcg_gen_ld_f32 tcg_gen_ld_i32
  1146 +#define tcg_gen_ld_f64 tcg_gen_ld_i64
  1147 +#define tcg_gen_st_f32 tcg_gen_st_i32
  1148 +#define tcg_gen_st_f64 tcg_gen_st_i64
  1149 +
1058 static inline void gen_mov_F0_vreg(int dp, int reg) 1150 static inline void gen_mov_F0_vreg(int dp, int reg)
1059 { 1151 {
1060 if (dp) 1152 if (dp)
1061 - gen_op_vfp_getreg_F0d(vfp_reg_offset(dp, reg)); 1153 + tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1062 else 1154 else
1063 - gen_op_vfp_getreg_F0s(vfp_reg_offset(dp, reg)); 1155 + tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1064 } 1156 }
1065 1157
1066 static inline void gen_mov_F1_vreg(int dp, int reg) 1158 static inline void gen_mov_F1_vreg(int dp, int reg)
1067 { 1159 {
1068 if (dp) 1160 if (dp)
1069 - gen_op_vfp_getreg_F1d(vfp_reg_offset(dp, reg)); 1161 + tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1070 else 1162 else
1071 - gen_op_vfp_getreg_F1s(vfp_reg_offset(dp, reg)); 1163 + tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1072 } 1164 }
1073 1165
1074 static inline void gen_mov_vreg_F0(int dp, int reg) 1166 static inline void gen_mov_vreg_F0(int dp, int reg)
1075 { 1167 {
1076 if (dp) 1168 if (dp)
1077 - gen_op_vfp_setreg_F0d(vfp_reg_offset(dp, reg)); 1169 + tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1078 else 1170 else
1079 - gen_op_vfp_setreg_F0s(vfp_reg_offset(dp, reg)); 1171 + tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1080 } 1172 }
1081 1173
1082 #define ARM_CP_RW_BIT (1 << 20) 1174 #define ARM_CP_RW_BIT (1 << 20)
@@ -2262,6 +2354,20 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn) @@ -2262,6 +2354,20 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2262 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5) 2354 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2263 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5) 2355 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2264 2356
  2357 +/* Move between integer and VFP cores. */
  2358 +static TCGv gen_vfp_mrs(void)
  2359 +{
  2360 + TCGv tmp = new_tmp();
  2361 + tcg_gen_mov_i32(tmp, cpu_F0s);
  2362 + return tmp;
  2363 +}
  2364 +
  2365 +static void gen_vfp_msr(TCGv tmp)
  2366 +{
  2367 + tcg_gen_mov_i32(cpu_F0s, tmp);
  2368 + dead_tmp(tmp);
  2369 +}
  2370 +
2265 static inline int 2371 static inline int
2266 vfp_enabled(CPUState * env) 2372 vfp_enabled(CPUState * env)
2267 { 2373 {
@@ -2274,6 +2380,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -2274,6 +2380,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2274 { 2380 {
2275 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask; 2381 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2276 int dp, veclen; 2382 int dp, veclen;
  2383 + TCGv tmp;
2277 2384
2278 if (!arm_feature(env, ARM_FEATURE_VFP)) 2385 if (!arm_feature(env, ARM_FEATURE_VFP))
2279 return 1; 2386 return 1;
@@ -2396,18 +2503,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -2396,18 +2503,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2396 2503
2397 switch (rn) { 2504 switch (rn) {
2398 case ARM_VFP_FPSID: 2505 case ARM_VFP_FPSID:
2399 - /* VFP2 allows access for FSID from userspace. 2506 + /* VFP2 allows access to FSID from userspace.
2400 VFP3 restricts all id registers to privileged 2507 VFP3 restricts all id registers to privileged
2401 accesses. */ 2508 accesses. */
2402 if (IS_USER(s) 2509 if (IS_USER(s)
2403 && arm_feature(env, ARM_FEATURE_VFP3)) 2510 && arm_feature(env, ARM_FEATURE_VFP3))
2404 return 1; 2511 return 1;
2405 - gen_op_vfp_movl_T0_xreg(rn); 2512 + tmp = load_cpu_field(vfp.xregs[rn]);
2406 break; 2513 break;
2407 case ARM_VFP_FPEXC: 2514 case ARM_VFP_FPEXC:
2408 if (IS_USER(s)) 2515 if (IS_USER(s))
2409 return 1; 2516 return 1;
2410 - gen_op_vfp_movl_T0_xreg(rn); 2517 + tmp = load_cpu_field(vfp.xregs[rn]);
2411 break; 2518 break;
2412 case ARM_VFP_FPINST: 2519 case ARM_VFP_FPINST:
2413 case ARM_VFP_FPINST2: 2520 case ARM_VFP_FPINST2:
@@ -2415,36 +2522,41 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -2415,36 +2522,41 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2415 if (IS_USER(s) 2522 if (IS_USER(s)
2416 || arm_feature(env, ARM_FEATURE_VFP3)) 2523 || arm_feature(env, ARM_FEATURE_VFP3))
2417 return 1; 2524 return 1;
2418 - gen_op_vfp_movl_T0_xreg(rn); 2525 + tmp = load_cpu_field(vfp.xregs[rn]);
2419 break; 2526 break;
2420 case ARM_VFP_FPSCR: 2527 case ARM_VFP_FPSCR:
2421 - if (rd == 15)  
2422 - gen_op_vfp_movl_T0_fpscr_flags();  
2423 - else  
2424 - gen_op_vfp_movl_T0_fpscr(); 2528 + if (rd == 15) {
  2529 + tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
  2530 + tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
  2531 + } else {
  2532 + tmp = new_tmp();
  2533 + gen_helper_vfp_get_fpscr(tmp, cpu_env);
  2534 + }
2425 break; 2535 break;
2426 case ARM_VFP_MVFR0: 2536 case ARM_VFP_MVFR0:
2427 case ARM_VFP_MVFR1: 2537 case ARM_VFP_MVFR1:
2428 if (IS_USER(s) 2538 if (IS_USER(s)
2429 || !arm_feature(env, ARM_FEATURE_VFP3)) 2539 || !arm_feature(env, ARM_FEATURE_VFP3))
2430 return 1; 2540 return 1;
2431 - gen_op_vfp_movl_T0_xreg(rn); 2541 + tmp = load_cpu_field(vfp.xregs[rn]);
2432 break; 2542 break;
2433 default: 2543 default:
2434 return 1; 2544 return 1;
2435 } 2545 }
2436 } else { 2546 } else {
2437 gen_mov_F0_vreg(0, rn); 2547 gen_mov_F0_vreg(0, rn);
2438 - gen_op_vfp_mrs(); 2548 + tmp = gen_vfp_mrs();
2439 } 2549 }
2440 if (rd == 15) { 2550 if (rd == 15) {
2441 /* Set the 4 flag bits in the CPSR. */ 2551 /* Set the 4 flag bits in the CPSR. */
2442 - gen_set_nzcv(cpu_T[0]);  
2443 - } else  
2444 - gen_movl_reg_T0(s, rd); 2552 + gen_set_nzcv(tmp);
  2553 + dead_tmp(tmp);
  2554 + } else {
  2555 + store_reg(s, rd, tmp);
  2556 + }
2445 } else { 2557 } else {
2446 /* arm->vfp */ 2558 /* arm->vfp */
2447 - gen_movl_T0_reg(s, rd); 2559 + tmp = load_reg(s, rd);
2448 if (insn & (1 << 21)) { 2560 if (insn & (1 << 21)) {
2449 rn >>= 1; 2561 rn >>= 1;
2450 /* system register */ 2562 /* system register */
@@ -2455,24 +2567,25 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -2455,24 +2567,25 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2455 /* Writes are ignored. */ 2567 /* Writes are ignored. */
2456 break; 2568 break;
2457 case ARM_VFP_FPSCR: 2569 case ARM_VFP_FPSCR:
2458 - gen_op_vfp_movl_fpscr_T0(); 2570 + gen_helper_vfp_set_fpscr(cpu_env, tmp);
  2571 + dead_tmp(tmp);
2459 gen_lookup_tb(s); 2572 gen_lookup_tb(s);
2460 break; 2573 break;
2461 case ARM_VFP_FPEXC: 2574 case ARM_VFP_FPEXC:
2462 if (IS_USER(s)) 2575 if (IS_USER(s))
2463 return 1; 2576 return 1;
2464 - gen_op_vfp_movl_xreg_T0(rn); 2577 + store_cpu_field(tmp, vfp.xregs[rn]);
2465 gen_lookup_tb(s); 2578 gen_lookup_tb(s);
2466 break; 2579 break;
2467 case ARM_VFP_FPINST: 2580 case ARM_VFP_FPINST:
2468 case ARM_VFP_FPINST2: 2581 case ARM_VFP_FPINST2:
2469 - gen_op_vfp_movl_xreg_T0(rn); 2582 + store_cpu_field(tmp, vfp.xregs[rn]);
2470 break; 2583 break;
2471 default: 2584 default:
2472 return 1; 2585 return 1;
2473 } 2586 }
2474 } else { 2587 } else {
2475 - gen_op_vfp_msr(); 2588 + gen_vfp_msr(tmp);
2476 gen_mov_vreg_F0(0, rn); 2589 gen_mov_vreg_F0(0, rn);
2477 } 2590 }
2478 } 2591 }
@@ -2640,14 +2753,15 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -2640,14 +2753,15 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2640 else 2753 else
2641 i |= 0x4000; 2754 i |= 0x4000;
2642 n |= i << 16; 2755 n |= i << 16;
  2756 + tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
2643 } else { 2757 } else {
2644 if (i & 0x40) 2758 if (i & 0x40)
2645 i |= 0x780; 2759 i |= 0x780;
2646 else 2760 else
2647 i |= 0x800; 2761 i |= 0x800;
2648 n |= i << 19; 2762 n |= i << 19;
  2763 + tcg_gen_movi_i32(cpu_F0d, ((uint64_t)n) << 32);
2649 } 2764 }
2650 - gen_vfp_fconst(dp, n);  
2651 break; 2765 break;
2652 case 15: /* extension space */ 2766 case 15: /* extension space */
2653 switch (rn) { 2767 switch (rn) {
@@ -2678,9 +2792,9 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -2678,9 +2792,9 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2678 break; 2792 break;
2679 case 15: /* single<->double conversion */ 2793 case 15: /* single<->double conversion */
2680 if (dp) 2794 if (dp)
2681 - gen_op_vfp_fcvtsd(); 2795 + gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
2682 else 2796 else
2683 - gen_op_vfp_fcvtds(); 2797 + gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
2684 break; 2798 break;
2685 case 16: /* fuito */ 2799 case 16: /* fuito */
2686 gen_vfp_uito(dp); 2800 gen_vfp_uito(dp);
@@ -2814,31 +2928,35 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -2814,31 +2928,35 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2814 if (insn & ARM_CP_RW_BIT) { 2928 if (insn & ARM_CP_RW_BIT) {
2815 /* vfp->arm */ 2929 /* vfp->arm */
2816 if (dp) { 2930 if (dp) {
2817 - gen_mov_F0_vreg(1, rm);  
2818 - gen_op_vfp_mrrd();  
2819 - gen_movl_reg_T0(s, rd);  
2820 - gen_movl_reg_T1(s, rn); 2931 + gen_mov_F0_vreg(0, rm * 2);
  2932 + tmp = gen_vfp_mrs();
  2933 + store_reg(s, rd, tmp);
  2934 + gen_mov_F0_vreg(0, rm * 2 + 1);
  2935 + tmp = gen_vfp_mrs();
  2936 + store_reg(s, rn, tmp);
2821 } else { 2937 } else {
2822 gen_mov_F0_vreg(0, rm); 2938 gen_mov_F0_vreg(0, rm);
2823 - gen_op_vfp_mrs();  
2824 - gen_movl_reg_T0(s, rn); 2939 + tmp = gen_vfp_mrs();
  2940 + store_reg(s, rn, tmp);
2825 gen_mov_F0_vreg(0, rm + 1); 2941 gen_mov_F0_vreg(0, rm + 1);
2826 - gen_op_vfp_mrs();  
2827 - gen_movl_reg_T0(s, rd); 2942 + tmp = gen_vfp_mrs();
  2943 + store_reg(s, rd, tmp);
2828 } 2944 }
2829 } else { 2945 } else {
2830 /* arm->vfp */ 2946 /* arm->vfp */
2831 if (dp) { 2947 if (dp) {
2832 - gen_movl_T0_reg(s, rd);  
2833 - gen_movl_T1_reg(s, rn);  
2834 - gen_op_vfp_mdrr();  
2835 - gen_mov_vreg_F0(1, rm); 2948 + tmp = load_reg(s, rd);
  2949 + gen_vfp_msr(tmp);
  2950 + gen_mov_vreg_F0(0, rm * 2);
  2951 + tmp = load_reg(s, rn);
  2952 + gen_vfp_msr(tmp);
  2953 + gen_mov_vreg_F0(0, rm * 2 + 1);
2836 } else { 2954 } else {
2837 - gen_movl_T0_reg(s, rn);  
2838 - gen_op_vfp_msr(); 2955 + tmp = load_reg(s, rn);
  2956 + gen_vfp_msr(tmp);
2839 gen_mov_vreg_F0(0, rm); 2957 gen_mov_vreg_F0(0, rm);
2840 - gen_movl_T0_reg(s, rd);  
2841 - gen_op_vfp_msr(); 2958 + tmp = load_reg(s, rd);
  2959 + gen_vfp_msr(tmp);
2842 gen_mov_vreg_F0(0, rm + 1); 2960 gen_mov_vreg_F0(0, rm + 1);
2843 } 2961 }
2844 } 2962 }
@@ -3993,9 +4111,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -3993,9 +4111,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
3993 break; 4111 break;
3994 case 31: 4112 case 31:
3995 if (size == 0) 4113 if (size == 0)
3996 - gen_op_neon_recps_f32(); 4114 + gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
3997 else 4115 else
3998 - gen_op_neon_rsqrts_f32(); 4116 + gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
3999 break; 4117 break;
4000 default: 4118 default:
4001 abort(); 4119 abort();
@@ -4242,19 +4360,19 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -4242,19 +4360,19 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4242 } else if (op == 15 || op == 16) { 4360 } else if (op == 15 || op == 16) {
4243 /* VCVT fixed-point. */ 4361 /* VCVT fixed-point. */
4244 for (pass = 0; pass < (q ? 4 : 2); pass++) { 4362 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4245 - gen_op_vfp_getreg_F0s(neon_reg_offset(rm, pass)); 4363 + tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4246 if (op & 1) { 4364 if (op & 1) {
4247 if (u) 4365 if (u)
4248 - gen_op_vfp_ultos(shift); 4366 + gen_vfp_ulto(0, shift);
4249 else 4367 else
4250 - gen_op_vfp_sltos(shift); 4368 + gen_vfp_slto(0, shift);
4251 } else { 4369 } else {
4252 if (u) 4370 if (u)
4253 - gen_op_vfp_touls(shift); 4371 + gen_vfp_toul(0, shift);
4254 else 4372 else
4255 - gen_op_vfp_tosls(shift); 4373 + gen_vfp_tosl(0, shift);
4256 } 4374 }
4257 - gen_op_vfp_setreg_F0s(neon_reg_offset(rd, pass)); 4375 + tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4258 } 4376 }
4259 } else { 4377 } else {
4260 return 1; 4378 return 1;
@@ -4898,7 +5016,8 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -4898,7 +5016,8 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4898 elementwise: 5016 elementwise:
4899 for (pass = 0; pass < (q ? 4 : 2); pass++) { 5017 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4900 if (op == 30 || op == 31 || op >= 58) { 5018 if (op == 30 || op == 31 || op >= 58) {
4901 - gen_op_vfp_getreg_F0s(neon_reg_offset(rm, pass)); 5019 + tcg_gen_ld_f32(cpu_F0s, cpu_env,
  5020 + neon_reg_offset(rm, pass));
4902 } else { 5021 } else {
4903 NEON_GET_REG(T0, rm, pass); 5022 NEON_GET_REG(T0, rm, pass);
4904 } 5023 }
@@ -5041,10 +5160,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -5041,10 +5160,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
5041 gen_op_neon_ceq_f32(); 5160 gen_op_neon_ceq_f32();
5042 break; 5161 break;
5043 case 30: /* Float VABS */ 5162 case 30: /* Float VABS */
5044 - gen_op_vfp_abss(); 5163 + gen_vfp_abs(0);
5045 break; 5164 break;
5046 case 31: /* Float VNEG */ 5165 case 31: /* Float VNEG */
5047 - gen_op_vfp_negs(); 5166 + gen_vfp_neg(0);
5048 break; 5167 break;
5049 case 32: /* VSWP */ 5168 case 32: /* VSWP */
5050 NEON_GET_REG(T1, rd, pass); 5169 NEON_GET_REG(T1, rd, pass);
@@ -5061,35 +5180,36 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -5061,35 +5180,36 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
5061 NEON_SET_REG(T1, rm, pass); 5180 NEON_SET_REG(T1, rm, pass);
5062 break; 5181 break;
5063 case 56: /* Integer VRECPE */ 5182 case 56: /* Integer VRECPE */
5064 - gen_op_neon_recpe_u32(); 5183 + gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
5065 break; 5184 break;
5066 case 57: /* Integer VRSQRTE */ 5185 case 57: /* Integer VRSQRTE */
5067 - gen_op_neon_rsqrte_u32(); 5186 + gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
5068 break; 5187 break;
5069 case 58: /* Float VRECPE */ 5188 case 58: /* Float VRECPE */
5070 - gen_op_neon_recpe_f32(); 5189 + gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5071 break; 5190 break;
5072 case 59: /* Float VRSQRTE */ 5191 case 59: /* Float VRSQRTE */
5073 - gen_op_neon_rsqrte_f32(); 5192 + gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5074 break; 5193 break;
5075 case 60: /* VCVT.F32.S32 */ 5194 case 60: /* VCVT.F32.S32 */
5076 - gen_op_vfp_tosizs(); 5195 + gen_vfp_tosiz(0);
5077 break; 5196 break;
5078 case 61: /* VCVT.F32.U32 */ 5197 case 61: /* VCVT.F32.U32 */
5079 - gen_op_vfp_touizs(); 5198 + gen_vfp_touiz(0);
5080 break; 5199 break;
5081 case 62: /* VCVT.S32.F32 */ 5200 case 62: /* VCVT.S32.F32 */
5082 - gen_op_vfp_sitos(); 5201 + gen_vfp_sito(0);
5083 break; 5202 break;
5084 case 63: /* VCVT.U32.F32 */ 5203 case 63: /* VCVT.U32.F32 */
5085 - gen_op_vfp_uitos(); 5204 + gen_vfp_uito(0);
5086 break; 5205 break;
5087 default: 5206 default:
5088 /* Reserved: 21, 29, 39-56 */ 5207 /* Reserved: 21, 29, 39-56 */
5089 return 1; 5208 return 1;
5090 } 5209 }
5091 if (op == 30 || op == 31 || op >= 58) { 5210 if (op == 30 || op == 31 || op >= 58) {
5092 - gen_op_vfp_setreg_F0s(neon_reg_offset(rm, pass)); 5211 + tcg_gen_st_f32(cpu_F0s, cpu_env,
  5212 + neon_reg_offset(rd, pass));
5093 } else { 5213 } else {
5094 NEON_SET_REG(T0, rd, pass); 5214 NEON_SET_REG(T0, rd, pass);
5095 } 5215 }
@@ -8062,6 +8182,10 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -8062,6 +8182,10 @@ static inline int gen_intermediate_code_internal(CPUState *env,
8062 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR; 8182 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8063 } 8183 }
8064 #endif 8184 #endif
  8185 + cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
  8186 + cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
  8187 + cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
  8188 + cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8065 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; 8189 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8066 lj = -1; 8190 lj = -1;
8067 /* Reset the conditional execution bits immediately. This avoids 8191 /* Reset the conditional execution bits immediately. This avoids