Commit 0487d6a8b4e15383d0651eea1e4e03ded44308b2
1 parent
75d62a58
PowerPC 2.03 SPE extension - first pass.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2519 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
9 changed files
with
3050 additions
and
146 deletions
target-ppc/cpu.h
... | ... | @@ -26,15 +26,20 @@ |
26 | 26 | #if defined (TARGET_PPC64) |
27 | 27 | typedef uint64_t ppc_gpr_t; |
28 | 28 | #define TARGET_LONG_BITS 64 |
29 | +#define TARGET_GPR_BITS 64 | |
29 | 30 | #define REGX "%016" PRIx64 |
30 | -#elif defined(TARGET_E500) | |
31 | +/* We can safely use PowerPC SPE extension when compiling PowerPC 64 */ | |
32 | +#define TARGET_PPCSPE | |
33 | +#elif defined(TARGET_PPCSPE) | |
31 | 34 | /* GPR are 64 bits: used by vector extension */ |
32 | 35 | typedef uint64_t ppc_gpr_t; |
33 | 36 | #define TARGET_LONG_BITS 32 |
37 | +#define TARGET_GPR_BITS 64 | |
34 | 38 | #define REGX "%08" PRIx32 |
35 | 39 | #else |
36 | 40 | typedef uint32_t ppc_gpr_t; |
37 | 41 | #define TARGET_LONG_BITS 32 |
42 | +#define TARGET_GPR_BITS 32 | |
38 | 43 | #define REGX "%08" PRIx32 |
39 | 44 | #endif |
40 | 45 | |
... | ... | @@ -297,7 +302,7 @@ enum { |
297 | 302 | /* ld/st with reservation instructions */ |
298 | 303 | /* cache control instructions */ |
299 | 304 | /* spr/msr access instructions */ |
300 | - PPC_INSNS_BASE = 0x00000001, | |
305 | + PPC_INSNS_BASE = 0x0000000000000001ULL, | |
301 | 306 | #define PPC_INTEGER PPC_INSNS_BASE |
302 | 307 | #define PPC_FLOW PPC_INSNS_BASE |
303 | 308 | #define PPC_MEM PPC_INSNS_BASE |
... | ... | @@ -305,68 +310,72 @@ enum { |
305 | 310 | #define PPC_CACHE PPC_INSNS_BASE |
306 | 311 | #define PPC_MISC PPC_INSNS_BASE |
307 | 312 | /* floating point operations instructions */ |
308 | - PPC_FLOAT = 0x00000002, | |
313 | + PPC_FLOAT = 0x0000000000000002ULL, | |
309 | 314 | /* more floating point operations instructions */ |
310 | - PPC_FLOAT_EXT = 0x00000004, | |
315 | + PPC_FLOAT_EXT = 0x0000000000000004ULL, | |
311 | 316 | /* external control instructions */ |
312 | - PPC_EXTERN = 0x00000008, | |
317 | + PPC_EXTERN = 0x0000000000000008ULL, | |
313 | 318 | /* segment register access instructions */ |
314 | - PPC_SEGMENT = 0x00000010, | |
319 | + PPC_SEGMENT = 0x0000000000000010ULL, | |
315 | 320 | /* Optional cache control instructions */ |
316 | - PPC_CACHE_OPT = 0x00000020, | |
321 | + PPC_CACHE_OPT = 0x0000000000000020ULL, | |
317 | 322 | /* Optional floating point op instructions */ |
318 | - PPC_FLOAT_OPT = 0x00000040, | |
323 | + PPC_FLOAT_OPT = 0x0000000000000040ULL, | |
319 | 324 | /* Optional memory control instructions */ |
320 | - PPC_MEM_TLBIA = 0x00000080, | |
321 | - PPC_MEM_TLBIE = 0x00000100, | |
322 | - PPC_MEM_TLBSYNC = 0x00000200, | |
325 | + PPC_MEM_TLBIA = 0x0000000000000080ULL, | |
326 | + PPC_MEM_TLBIE = 0x0000000000000100ULL, | |
327 | + PPC_MEM_TLBSYNC = 0x0000000000000200ULL, | |
323 | 328 | /* eieio & sync */ |
324 | - PPC_MEM_SYNC = 0x00000400, | |
329 | + PPC_MEM_SYNC = 0x0000000000000400ULL, | |
325 | 330 | /* PowerPC 6xx TLB management instructions */ |
326 | - PPC_6xx_TLB = 0x00000800, | |
331 | + PPC_6xx_TLB = 0x0000000000000800ULL, | |
327 | 332 | /* Altivec support */ |
328 | - PPC_ALTIVEC = 0x00001000, | |
333 | + PPC_ALTIVEC = 0x0000000000001000ULL, | |
329 | 334 | /* Time base support */ |
330 | - PPC_TB = 0x00002000, | |
335 | + PPC_TB = 0x0000000000002000ULL, | |
331 | 336 | /* Embedded PowerPC dedicated instructions */ |
332 | - PPC_EMB_COMMON = 0x00004000, | |
337 | + PPC_EMB_COMMON = 0x0000000000004000ULL, | |
333 | 338 | /* PowerPC 40x exception model */ |
334 | - PPC_40x_EXCP = 0x00008000, | |
339 | + PPC_40x_EXCP = 0x0000000000008000ULL, | |
335 | 340 | /* PowerPC 40x specific instructions */ |
336 | - PPC_40x_SPEC = 0x00010000, | |
341 | + PPC_40x_SPEC = 0x0000000000010000ULL, | |
337 | 342 | /* PowerPC 405 Mac instructions */ |
338 | - PPC_405_MAC = 0x00020000, | |
343 | + PPC_405_MAC = 0x0000000000020000ULL, | |
339 | 344 | /* PowerPC 440 specific instructions */ |
340 | - PPC_440_SPEC = 0x00040000, | |
345 | + PPC_440_SPEC = 0x0000000000040000ULL, | |
341 | 346 | /* Specific extensions */ |
342 | 347 | /* Power-to-PowerPC bridge (601) */ |
343 | - PPC_POWER_BR = 0x00080000, | |
348 | + PPC_POWER_BR = 0x0000000000080000ULL, | |
344 | 349 | /* PowerPC 602 specific */ |
345 | - PPC_602_SPEC = 0x00100000, | |
350 | + PPC_602_SPEC = 0x0000000000100000ULL, | |
346 | 351 | /* Deprecated instructions */ |
347 | 352 | /* Original POWER instruction set */ |
348 | - PPC_POWER = 0x00200000, | |
353 | + PPC_POWER = 0x0000000000200000ULL, | |
349 | 354 | /* POWER2 instruction set extension */ |
350 | - PPC_POWER2 = 0x00400000, | |
355 | + PPC_POWER2 = 0x0000000000400000ULL, | |
351 | 356 | /* Power RTC support */ |
352 | - PPC_POWER_RTC = 0x00800000, | |
357 | + PPC_POWER_RTC = 0x0000000000800000ULL, | |
353 | 358 | /* 64 bits PowerPC instructions */ |
354 | 359 | /* 64 bits PowerPC instruction set */ |
355 | - PPC_64B = 0x01000000, | |
360 | + PPC_64B = 0x0000000001000000ULL, | |
356 | 361 | /* 64 bits hypervisor extensions */ |
357 | - PPC_64H = 0x02000000, | |
362 | + PPC_64H = 0x0000000002000000ULL, | |
358 | 363 | /* 64 bits PowerPC "bridge" features */ |
359 | - PPC_64_BRIDGE = 0x04000000, | |
364 | + PPC_64_BRIDGE = 0x0000000004000000ULL, | |
360 | 365 | /* BookE (embedded) PowerPC specification */ |
361 | - PPC_BOOKE = 0x08000000, | |
366 | + PPC_BOOKE = 0x0000000008000000ULL, | |
362 | 367 | /* eieio */ |
363 | - PPC_MEM_EIEIO = 0x10000000, | |
368 | + PPC_MEM_EIEIO = 0x0000000010000000ULL, | |
364 | 369 | /* e500 vector instructions */ |
365 | - PPC_E500_VECTOR = 0x20000000, | |
370 | + PPC_E500_VECTOR = 0x0000000020000000ULL, | |
366 | 371 | /* PowerPC 4xx dedicated instructions */ |
367 | - PPC_4xx_COMMON = 0x40000000, | |
372 | + PPC_4xx_COMMON = 0x0000000040000000ULL, | |
368 | 373 | /* PowerPC 2.03 specification extensions */ |
369 | - PPC_203 = 0x80000000, | |
374 | + PPC_203 = 0x0000000080000000ULL, | |
375 | + /* PowerPC 2.03 SPE extension */ | |
376 | + PPC_SPE = 0x0000000100000000ULL, | |
377 | + /* PowerPC 2.03 SPE floating-point extension */ | |
378 | + PPC_SPEFPU = 0x0000000200000000ULL, | |
370 | 379 | }; |
371 | 380 | |
372 | 381 | /* CPU run-time flags (MMU and exception model) */ |
... | ... | @@ -618,10 +627,10 @@ struct CPUPPCState { |
618 | 627 | /* First are the most commonly used resources |
619 | 628 | * during translated code execution |
620 | 629 | */ |
621 | -#if TARGET_LONG_BITS > HOST_LONG_BITS | |
630 | +#if TARGET_GPR_BITS > HOST_LONG_BITS | |
622 | 631 | /* temporary fixed-point registers |
623 | 632 | * used to emulate 64 bits target on 32 bits hosts |
624 | - */ | |
633 | + */ | |
625 | 634 | target_ulong t0, t1, t2; |
626 | 635 | #endif |
627 | 636 | ppc_avr_t t0_avr, t1_avr, t2_avr; |
... | ... | @@ -683,6 +692,7 @@ struct CPUPPCState { |
683 | 692 | uint32_t vscr; |
684 | 693 | /* SPE registers */ |
685 | 694 | ppc_gpr_t spe_acc; |
695 | + float_status spe_status; | |
686 | 696 | uint32_t spe_fscr; |
687 | 697 | |
688 | 698 | /* Internal devices resources */ |
... | ... | @@ -1192,6 +1202,8 @@ enum { |
1192 | 1202 | #define EXCP_970_MAINT 0x1600 /* Maintenance exception */ |
1193 | 1203 | #define EXCP_970_THRM 0x1800 /* Thermal exception */ |
1194 | 1204 | #define EXCP_970_VPUA 0x1700 /* VPU assist exception */ |
1205 | +/* SPE related exceptions */ | |
1206 | +#define EXCP_NO_SPE 0x0F20 /* SPE unavailable exception */ | |
1195 | 1207 | /* End of exception vectors area */ |
1196 | 1208 | #define EXCP_PPC_MAX 0x4000 |
1197 | 1209 | /* Qemu exceptions: special cases we want to stop translation */ | ... | ... |
target-ppc/exec.h
... | ... | @@ -39,10 +39,10 @@ register unsigned long T1 asm(AREG2); |
39 | 39 | register unsigned long T2 asm(AREG3); |
40 | 40 | #endif |
41 | 41 | /* We may, sometime, need 64 bits registers on 32 bits target */ |
42 | -#if defined(TARGET_PPC64) || (HOST_LONG_BITS == 64) | |
42 | +#if defined(TARGET_PPC64) || defined(TARGET_PPCSPE) || (HOST_LONG_BITS == 64) | |
43 | 43 | #define T0_64 T0 |
44 | -#define T1_64 T0 | |
45 | -#define T2_64 T0 | |
44 | +#define T1_64 T1 | |
45 | +#define T2_64 T2 | |
46 | 46 | #else |
47 | 47 | /* no registers can be used */ |
48 | 48 | #define T0_64 (env->t0) | ... | ... |
target-ppc/op.c
... | ... | @@ -1326,106 +1326,14 @@ void OPPROTO op_andi_T1 (void) |
1326 | 1326 | /* count leading zero */ |
1327 | 1327 | void OPPROTO op_cntlzw (void) |
1328 | 1328 | { |
1329 | - int cnt; | |
1330 | - | |
1331 | - cnt = 0; | |
1332 | - if (!(T0 & 0xFFFF0000UL)) { | |
1333 | - cnt += 16; | |
1334 | - T0 <<= 16; | |
1335 | - } | |
1336 | - if (!(T0 & 0xFF000000UL)) { | |
1337 | - cnt += 8; | |
1338 | - T0 <<= 8; | |
1339 | - } | |
1340 | - if (!(T0 & 0xF0000000UL)) { | |
1341 | - cnt += 4; | |
1342 | - T0 <<= 4; | |
1343 | - } | |
1344 | - if (!(T0 & 0xC0000000UL)) { | |
1345 | - cnt += 2; | |
1346 | - T0 <<= 2; | |
1347 | - } | |
1348 | - if (!(T0 & 0x80000000UL)) { | |
1349 | - cnt++; | |
1350 | - T0 <<= 1; | |
1351 | - } | |
1352 | - if (!(T0 & 0x80000000UL)) { | |
1353 | - cnt++; | |
1354 | - } | |
1355 | - T0 = cnt; | |
1329 | + T0 = _do_cntlzw(T0); | |
1356 | 1330 | RETURN(); |
1357 | 1331 | } |
1358 | 1332 | |
1359 | 1333 | #if defined(TARGET_PPC64) |
1360 | 1334 | void OPPROTO op_cntlzd (void) |
1361 | 1335 | { |
1362 | -#if HOST_LONG_BITS == 64 | |
1363 | - int cnt; | |
1364 | - | |
1365 | - cnt = 0; | |
1366 | - if (!(T0 & 0xFFFFFFFF00000000ULL)) { | |
1367 | - cnt += 32; | |
1368 | - T0 <<= 32; | |
1369 | - } | |
1370 | - if (!(T0 & 0xFFFF000000000000ULL)) { | |
1371 | - cnt += 16; | |
1372 | - T0 <<= 16; | |
1373 | - } | |
1374 | - if (!(T0 & 0xFF00000000000000ULL)) { | |
1375 | - cnt += 8; | |
1376 | - T0 <<= 8; | |
1377 | - } | |
1378 | - if (!(T0 & 0xF000000000000000ULL)) { | |
1379 | - cnt += 4; | |
1380 | - T0 <<= 4; | |
1381 | - } | |
1382 | - if (!(T0 & 0xC000000000000000ULL)) { | |
1383 | - cnt += 2; | |
1384 | - T0 <<= 2; | |
1385 | - } | |
1386 | - if (!(T0 & 0x8000000000000000ULL)) { | |
1387 | - cnt++; | |
1388 | - T0 <<= 1; | |
1389 | - } | |
1390 | - if (!(T0 & 0x8000000000000000ULL)) { | |
1391 | - cnt++; | |
1392 | - } | |
1393 | - T0 = cnt; | |
1394 | -#else | |
1395 | - uint32_t tmp; | |
1396 | - | |
1397 | - /* Make it easier on 32 bits host machines */ | |
1398 | - if (!(T0 >> 32)) { | |
1399 | - tmp = T0; | |
1400 | - T0 = 32; | |
1401 | - } else { | |
1402 | - tmp = T0 >> 32; | |
1403 | - T0 = 0; | |
1404 | - } | |
1405 | - if (!(tmp & 0xFFFF0000UL)) { | |
1406 | - T0 += 16; | |
1407 | - tmp <<= 16; | |
1408 | - } | |
1409 | - if (!(tmp & 0xFF000000UL)) { | |
1410 | - T0 += 8; | |
1411 | - tmp <<= 8; | |
1412 | - } | |
1413 | - if (!(tmp & 0xF0000000UL)) { | |
1414 | - T0 += 4; | |
1415 | - tmp <<= 4; | |
1416 | - } | |
1417 | - if (!(tmp & 0xC0000000UL)) { | |
1418 | - T0 += 2; | |
1419 | - tmp <<= 2; | |
1420 | - } | |
1421 | - if (!(tmp & 0x80000000UL)) { | |
1422 | - T0++; | |
1423 | - tmp <<= 1; | |
1424 | - } | |
1425 | - if (!(tmp & 0x80000000UL)) { | |
1426 | - T0++; | |
1427 | - } | |
1428 | -#endif | |
1336 | + T0 = _do_cntlzd(T0); | |
1429 | 1337 | RETURN(); |
1430 | 1338 | } |
1431 | 1339 | #endif |
... | ... | @@ -2462,4 +2370,723 @@ void OPPROTO op_store_booke_tsr (void) |
2462 | 2370 | store_booke_tsr(env, T0); |
2463 | 2371 | RETURN(); |
2464 | 2372 | } |
2373 | + | |
2465 | 2374 | #endif /* !defined(CONFIG_USER_ONLY) */ |
2375 | + | |
2376 | +#if defined(TARGET_PPCSPE) | |
2377 | +/* SPE extension */ | |
2378 | +void OPPROTO op_splatw_T1_64 (void) | |
2379 | +{ | |
2380 | + T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL); | |
2381 | +} | |
2382 | + | |
2383 | +void OPPROTO op_splatwi_T0_64 (void) | |
2384 | +{ | |
2385 | + uint64_t tmp = PARAM1; | |
2386 | + | |
2387 | + T0_64 = (tmp << 32) | tmp; | |
2388 | +} | |
2389 | + | |
2390 | +void OPPROTO op_splatwi_T1_64 (void) | |
2391 | +{ | |
2392 | + uint64_t tmp = PARAM1; | |
2393 | + | |
2394 | + T1_64 = (tmp << 32) | tmp; | |
2395 | +} | |
2396 | + | |
2397 | +void OPPROTO op_extsh_T1_64 (void) | |
2398 | +{ | |
2399 | + T1_64 = (int32_t)((int16_t)T1_64); | |
2400 | + RETURN(); | |
2401 | +} | |
2402 | + | |
2403 | +void OPPROTO op_sli16_T1_64 (void) | |
2404 | +{ | |
2405 | + T1_64 = T1_64 << 16; | |
2406 | + RETURN(); | |
2407 | +} | |
2408 | + | |
2409 | +void OPPROTO op_sli32_T1_64 (void) | |
2410 | +{ | |
2411 | + T1_64 = T1_64 << 32; | |
2412 | + RETURN(); | |
2413 | +} | |
2414 | + | |
2415 | +void OPPROTO op_srli32_T1_64 (void) | |
2416 | +{ | |
2417 | + T1_64 = T1_64 >> 32; | |
2418 | + RETURN(); | |
2419 | +} | |
2420 | + | |
2421 | +void OPPROTO op_evsel (void) | |
2422 | +{ | |
2423 | + do_evsel(); | |
2424 | + RETURN(); | |
2425 | +} | |
2426 | + | |
2427 | +void OPPROTO op_evaddw (void) | |
2428 | +{ | |
2429 | + do_evaddw(); | |
2430 | + RETURN(); | |
2431 | +} | |
2432 | + | |
2433 | +void OPPROTO op_evsubfw (void) | |
2434 | +{ | |
2435 | + do_evsubfw(); | |
2436 | + RETURN(); | |
2437 | +} | |
2438 | + | |
2439 | +void OPPROTO op_evneg (void) | |
2440 | +{ | |
2441 | + do_evneg(); | |
2442 | + RETURN(); | |
2443 | +} | |
2444 | + | |
2445 | +void OPPROTO op_evabs (void) | |
2446 | +{ | |
2447 | + do_evabs(); | |
2448 | + RETURN(); | |
2449 | +} | |
2450 | + | |
2451 | +void OPPROTO op_evextsh (void) | |
2452 | +{ | |
2453 | + T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) | | |
2454 | + (uint64_t)((int32_t)(int16_t)T0_64); | |
2455 | + RETURN(); | |
2456 | +} | |
2457 | + | |
2458 | +void OPPROTO op_evextsb (void) | |
2459 | +{ | |
2460 | + T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) | | |
2461 | + (uint64_t)((int32_t)(int8_t)T0_64); | |
2462 | + RETURN(); | |
2463 | +} | |
2464 | + | |
2465 | +void OPPROTO op_evcntlzw (void) | |
2466 | +{ | |
2467 | + do_evcntlzw(); | |
2468 | + RETURN(); | |
2469 | +} | |
2470 | + | |
2471 | +void OPPROTO op_evrndw (void) | |
2472 | +{ | |
2473 | + do_evrndw(); | |
2474 | + RETURN(); | |
2475 | +} | |
2476 | + | |
2477 | +void OPPROTO op_brinc (void) | |
2478 | +{ | |
2479 | + do_brinc(); | |
2480 | + RETURN(); | |
2481 | +} | |
2482 | + | |
2483 | +void OPPROTO op_evcntlsw (void) | |
2484 | +{ | |
2485 | + do_evcntlsw(); | |
2486 | + RETURN(); | |
2487 | +} | |
2488 | + | |
2489 | +void OPPROTO op_evand (void) | |
2490 | +{ | |
2491 | + T0_64 &= T1_64; | |
2492 | + RETURN(); | |
2493 | +} | |
2494 | + | |
2495 | +void OPPROTO op_evandc (void) | |
2496 | +{ | |
2497 | + T0_64 &= ~T1_64; | |
2498 | + RETURN(); | |
2499 | +} | |
2500 | + | |
2501 | +void OPPROTO op_evor (void) | |
2502 | +{ | |
2503 | + T0_64 |= T1_64; | |
2504 | + RETURN(); | |
2505 | +} | |
2506 | + | |
2507 | +void OPPROTO op_evxor (void) | |
2508 | +{ | |
2509 | + T0_64 ^= T1_64; | |
2510 | + RETURN(); | |
2511 | +} | |
2512 | + | |
2513 | +void OPPROTO op_eveqv (void) | |
2514 | +{ | |
2515 | + T0_64 = ~(T0_64 ^ T1_64); | |
2516 | + RETURN(); | |
2517 | +} | |
2518 | + | |
2519 | +void OPPROTO op_evnor (void) | |
2520 | +{ | |
2521 | + T0_64 = ~(T0_64 | T1_64); | |
2522 | + RETURN(); | |
2523 | +} | |
2524 | + | |
2525 | +void OPPROTO op_evorc (void) | |
2526 | +{ | |
2527 | + T0_64 |= ~T1_64; | |
2528 | + RETURN(); | |
2529 | +} | |
2530 | + | |
2531 | +void OPPROTO op_evnand (void) | |
2532 | +{ | |
2533 | + T0_64 = ~(T0_64 & T1_64); | |
2534 | + RETURN(); | |
2535 | +} | |
2536 | + | |
2537 | +void OPPROTO op_evsrws (void) | |
2538 | +{ | |
2539 | + do_evsrws(); | |
2540 | + RETURN(); | |
2541 | +} | |
2542 | + | |
2543 | +void OPPROTO op_evsrwu (void) | |
2544 | +{ | |
2545 | + do_evsrwu(); | |
2546 | + RETURN(); | |
2547 | +} | |
2548 | + | |
2549 | +void OPPROTO op_evslw (void) | |
2550 | +{ | |
2551 | + do_evslw(); | |
2552 | + RETURN(); | |
2553 | +} | |
2554 | + | |
2555 | +void OPPROTO op_evrlw (void) | |
2556 | +{ | |
2557 | + do_evrlw(); | |
2558 | + RETURN(); | |
2559 | +} | |
2560 | + | |
2561 | +void OPPROTO op_evmergelo (void) | |
2562 | +{ | |
2563 | + T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL); | |
2564 | + RETURN(); | |
2565 | +} | |
2566 | + | |
2567 | +void OPPROTO op_evmergehi (void) | |
2568 | +{ | |
2569 | + T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32); | |
2570 | + RETURN(); | |
2571 | +} | |
2572 | + | |
2573 | +void OPPROTO op_evmergelohi (void) | |
2574 | +{ | |
2575 | + T0_64 = (T0_64 << 32) | (T1_64 >> 32); | |
2576 | + RETURN(); | |
2577 | +} | |
2578 | + | |
2579 | +void OPPROTO op_evmergehilo (void) | |
2580 | +{ | |
2581 | + T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL); | |
2582 | + RETURN(); | |
2583 | +} | |
2584 | + | |
2585 | +void OPPROTO op_evcmpgts (void) | |
2586 | +{ | |
2587 | + do_evcmpgts(); | |
2588 | + RETURN(); | |
2589 | +} | |
2590 | + | |
2591 | +void OPPROTO op_evcmpgtu (void) | |
2592 | +{ | |
2593 | + do_evcmpgtu(); | |
2594 | + RETURN(); | |
2595 | +} | |
2596 | + | |
2597 | +void OPPROTO op_evcmplts (void) | |
2598 | +{ | |
2599 | + do_evcmplts(); | |
2600 | + RETURN(); | |
2601 | +} | |
2602 | + | |
2603 | +void OPPROTO op_evcmpltu (void) | |
2604 | +{ | |
2605 | + do_evcmpltu(); | |
2606 | + RETURN(); | |
2607 | +} | |
2608 | + | |
2609 | +void OPPROTO op_evcmpeq (void) | |
2610 | +{ | |
2611 | + do_evcmpeq(); | |
2612 | + RETURN(); | |
2613 | +} | |
2614 | + | |
2615 | +void OPPROTO op_evfssub (void) | |
2616 | +{ | |
2617 | + do_evfssub(); | |
2618 | + RETURN(); | |
2619 | +} | |
2620 | + | |
2621 | +void OPPROTO op_evfsadd (void) | |
2622 | +{ | |
2623 | + do_evfsadd(); | |
2624 | + RETURN(); | |
2625 | +} | |
2626 | + | |
2627 | +void OPPROTO op_evfsnabs (void) | |
2628 | +{ | |
2629 | + do_evfsnabs(); | |
2630 | + RETURN(); | |
2631 | +} | |
2632 | + | |
2633 | +void OPPROTO op_evfsabs (void) | |
2634 | +{ | |
2635 | + do_evfsabs(); | |
2636 | + RETURN(); | |
2637 | +} | |
2638 | + | |
2639 | +void OPPROTO op_evfsneg (void) | |
2640 | +{ | |
2641 | + do_evfsneg(); | |
2642 | + RETURN(); | |
2643 | +} | |
2644 | + | |
2645 | +void OPPROTO op_evfsdiv (void) | |
2646 | +{ | |
2647 | + do_evfsdiv(); | |
2648 | + RETURN(); | |
2649 | +} | |
2650 | + | |
2651 | +void OPPROTO op_evfsmul (void) | |
2652 | +{ | |
2653 | + do_evfsmul(); | |
2654 | + RETURN(); | |
2655 | +} | |
2656 | + | |
2657 | +void OPPROTO op_evfscmplt (void) | |
2658 | +{ | |
2659 | + do_evfscmplt(); | |
2660 | + RETURN(); | |
2661 | +} | |
2662 | + | |
2663 | +void OPPROTO op_evfscmpgt (void) | |
2664 | +{ | |
2665 | + do_evfscmpgt(); | |
2666 | + RETURN(); | |
2667 | +} | |
2668 | + | |
2669 | +void OPPROTO op_evfscmpeq (void) | |
2670 | +{ | |
2671 | + do_evfscmpeq(); | |
2672 | + RETURN(); | |
2673 | +} | |
2674 | + | |
2675 | +void OPPROTO op_evfscfsi (void) | |
2676 | +{ | |
2677 | + do_evfscfsi(); | |
2678 | + RETURN(); | |
2679 | +} | |
2680 | + | |
2681 | +void OPPROTO op_evfscfui (void) | |
2682 | +{ | |
2683 | + do_evfscfui(); | |
2684 | + RETURN(); | |
2685 | +} | |
2686 | + | |
2687 | +void OPPROTO op_evfscfsf (void) | |
2688 | +{ | |
2689 | + do_evfscfsf(); | |
2690 | + RETURN(); | |
2691 | +} | |
2692 | + | |
2693 | +void OPPROTO op_evfscfuf (void) | |
2694 | +{ | |
2695 | + do_evfscfuf(); | |
2696 | + RETURN(); | |
2697 | +} | |
2698 | + | |
2699 | +void OPPROTO op_evfsctsi (void) | |
2700 | +{ | |
2701 | + do_evfsctsi(); | |
2702 | + RETURN(); | |
2703 | +} | |
2704 | + | |
2705 | +void OPPROTO op_evfsctui (void) | |
2706 | +{ | |
2707 | + do_evfsctui(); | |
2708 | + RETURN(); | |
2709 | +} | |
2710 | + | |
2711 | +void OPPROTO op_evfsctsf (void) | |
2712 | +{ | |
2713 | + do_evfsctsf(); | |
2714 | + RETURN(); | |
2715 | +} | |
2716 | + | |
2717 | +void OPPROTO op_evfsctuf (void) | |
2718 | +{ | |
2719 | + do_evfsctuf(); | |
2720 | + RETURN(); | |
2721 | +} | |
2722 | + | |
2723 | +void OPPROTO op_evfsctuiz (void) | |
2724 | +{ | |
2725 | + do_evfsctuiz(); | |
2726 | + RETURN(); | |
2727 | +} | |
2728 | + | |
2729 | +void OPPROTO op_evfsctsiz (void) | |
2730 | +{ | |
2731 | + do_evfsctsiz(); | |
2732 | + RETURN(); | |
2733 | +} | |
2734 | + | |
2735 | +void OPPROTO op_evfststlt (void) | |
2736 | +{ | |
2737 | + do_evfststlt(); | |
2738 | + RETURN(); | |
2739 | +} | |
2740 | + | |
2741 | +void OPPROTO op_evfststgt (void) | |
2742 | +{ | |
2743 | + do_evfststgt(); | |
2744 | + RETURN(); | |
2745 | +} | |
2746 | + | |
2747 | +void OPPROTO op_evfststeq (void) | |
2748 | +{ | |
2749 | + do_evfststeq(); | |
2750 | + RETURN(); | |
2751 | +} | |
2752 | + | |
2753 | +void OPPROTO op_efssub (void) | |
2754 | +{ | |
2755 | + T0_64 = _do_efssub(T0_64, T1_64); | |
2756 | + RETURN(); | |
2757 | +} | |
2758 | + | |
2759 | +void OPPROTO op_efsadd (void) | |
2760 | +{ | |
2761 | + T0_64 = _do_efsadd(T0_64, T1_64); | |
2762 | + RETURN(); | |
2763 | +} | |
2764 | + | |
2765 | +void OPPROTO op_efsnabs (void) | |
2766 | +{ | |
2767 | + T0_64 = _do_efsnabs(T0_64); | |
2768 | + RETURN(); | |
2769 | +} | |
2770 | + | |
2771 | +void OPPROTO op_efsabs (void) | |
2772 | +{ | |
2773 | + T0_64 = _do_efsabs(T0_64); | |
2774 | + RETURN(); | |
2775 | +} | |
2776 | + | |
2777 | +void OPPROTO op_efsneg (void) | |
2778 | +{ | |
2779 | + T0_64 = _do_efsneg(T0_64); | |
2780 | + RETURN(); | |
2781 | +} | |
2782 | + | |
2783 | +void OPPROTO op_efsdiv (void) | |
2784 | +{ | |
2785 | + T0_64 = _do_efsdiv(T0_64, T1_64); | |
2786 | + RETURN(); | |
2787 | +} | |
2788 | + | |
2789 | +void OPPROTO op_efsmul (void) | |
2790 | +{ | |
2791 | + T0_64 = _do_efsmul(T0_64, T1_64); | |
2792 | + RETURN(); | |
2793 | +} | |
2794 | + | |
2795 | +void OPPROTO op_efscmplt (void) | |
2796 | +{ | |
2797 | + do_efscmplt(); | |
2798 | + RETURN(); | |
2799 | +} | |
2800 | + | |
2801 | +void OPPROTO op_efscmpgt (void) | |
2802 | +{ | |
2803 | + do_efscmpgt(); | |
2804 | + RETURN(); | |
2805 | +} | |
2806 | + | |
2807 | +void OPPROTO op_efscfd (void) | |
2808 | +{ | |
2809 | + do_efscfd(); | |
2810 | + RETURN(); | |
2811 | +} | |
2812 | + | |
2813 | +void OPPROTO op_efscmpeq (void) | |
2814 | +{ | |
2815 | + do_efscmpeq(); | |
2816 | + RETURN(); | |
2817 | +} | |
2818 | + | |
2819 | +void OPPROTO op_efscfsi (void) | |
2820 | +{ | |
2821 | + do_efscfsi(); | |
2822 | + RETURN(); | |
2823 | +} | |
2824 | + | |
2825 | +void OPPROTO op_efscfui (void) | |
2826 | +{ | |
2827 | + do_efscfui(); | |
2828 | + RETURN(); | |
2829 | +} | |
2830 | + | |
2831 | +void OPPROTO op_efscfsf (void) | |
2832 | +{ | |
2833 | + do_efscfsf(); | |
2834 | + RETURN(); | |
2835 | +} | |
2836 | + | |
2837 | +void OPPROTO op_efscfuf (void) | |
2838 | +{ | |
2839 | + do_efscfuf(); | |
2840 | + RETURN(); | |
2841 | +} | |
2842 | + | |
2843 | +void OPPROTO op_efsctsi (void) | |
2844 | +{ | |
2845 | + do_efsctsi(); | |
2846 | + RETURN(); | |
2847 | +} | |
2848 | + | |
2849 | +void OPPROTO op_efsctui (void) | |
2850 | +{ | |
2851 | + do_efsctui(); | |
2852 | + RETURN(); | |
2853 | +} | |
2854 | + | |
2855 | +void OPPROTO op_efsctsf (void) | |
2856 | +{ | |
2857 | + do_efsctsf(); | |
2858 | + RETURN(); | |
2859 | +} | |
2860 | + | |
2861 | +void OPPROTO op_efsctuf (void) | |
2862 | +{ | |
2863 | + do_efsctuf(); | |
2864 | + RETURN(); | |
2865 | +} | |
2866 | + | |
2867 | +void OPPROTO op_efsctsiz (void) | |
2868 | +{ | |
2869 | + do_efsctsiz(); | |
2870 | + RETURN(); | |
2871 | +} | |
2872 | + | |
2873 | +void OPPROTO op_efsctuiz (void) | |
2874 | +{ | |
2875 | + do_efsctuiz(); | |
2876 | + RETURN(); | |
2877 | +} | |
2878 | + | |
2879 | +void OPPROTO op_efststlt (void) | |
2880 | +{ | |
2881 | + T0 = _do_efststlt(T0_64, T1_64); | |
2882 | + RETURN(); | |
2883 | +} | |
2884 | + | |
2885 | +void OPPROTO op_efststgt (void) | |
2886 | +{ | |
2887 | + T0 = _do_efststgt(T0_64, T1_64); | |
2888 | + RETURN(); | |
2889 | +} | |
2890 | + | |
2891 | +void OPPROTO op_efststeq (void) | |
2892 | +{ | |
2893 | + T0 = _do_efststeq(T0_64, T1_64); | |
2894 | + RETURN(); | |
2895 | +} | |
2896 | + | |
2897 | +void OPPROTO op_efdsub (void) | |
2898 | +{ | |
2899 | + union { | |
2900 | + uint64_t u; | |
2901 | + float64 f; | |
2902 | + } u1, u2; | |
2903 | + u1.u = T0_64; | |
2904 | + u2.u = T1_64; | |
2905 | + u1.f = float64_sub(u1.f, u2.f, &env->spe_status); | |
2906 | + T0_64 = u1.u; | |
2907 | + RETURN(); | |
2908 | +} | |
2909 | + | |
2910 | +void OPPROTO op_efdadd (void) | |
2911 | +{ | |
2912 | + union { | |
2913 | + uint64_t u; | |
2914 | + float64 f; | |
2915 | + } u1, u2; | |
2916 | + u1.u = T0_64; | |
2917 | + u2.u = T1_64; | |
2918 | + u1.f = float64_add(u1.f, u2.f, &env->spe_status); | |
2919 | + T0_64 = u1.u; | |
2920 | + RETURN(); | |
2921 | +} | |
2922 | + | |
2923 | +void OPPROTO op_efdcfsid (void) | |
2924 | +{ | |
2925 | + do_efdcfsi(); | |
2926 | + RETURN(); | |
2927 | +} | |
2928 | + | |
2929 | +void OPPROTO op_efdcfuid (void) | |
2930 | +{ | |
2931 | + do_efdcfui(); | |
2932 | + RETURN(); | |
2933 | +} | |
2934 | + | |
2935 | +void OPPROTO op_efdnabs (void) | |
2936 | +{ | |
2937 | + T0_64 |= 0x8000000000000000ULL; | |
2938 | + RETURN(); | |
2939 | +} | |
2940 | + | |
2941 | +void OPPROTO op_efdabs (void) | |
2942 | +{ | |
2943 | + T0_64 &= ~0x8000000000000000ULL; | |
2944 | + RETURN(); | |
2945 | +} | |
2946 | + | |
2947 | +void OPPROTO op_efdneg (void) | |
2948 | +{ | |
2949 | + T0_64 ^= 0x8000000000000000ULL; | |
2950 | + RETURN(); | |
2951 | +} | |
2952 | + | |
2953 | +void OPPROTO op_efddiv (void) | |
2954 | +{ | |
2955 | + union { | |
2956 | + uint64_t u; | |
2957 | + float64 f; | |
2958 | + } u1, u2; | |
2959 | + u1.u = T0_64; | |
2960 | + u2.u = T1_64; | |
2961 | + u1.f = float64_div(u1.f, u2.f, &env->spe_status); | |
2962 | + T0_64 = u1.u; | |
2963 | + RETURN(); | |
2964 | +} | |
2965 | + | |
2966 | +void OPPROTO op_efdmul (void) | |
2967 | +{ | |
2968 | + union { | |
2969 | + uint64_t u; | |
2970 | + float64 f; | |
2971 | + } u1, u2; | |
2972 | + u1.u = T0_64; | |
2973 | + u2.u = T1_64; | |
2974 | + u1.f = float64_mul(u1.f, u2.f, &env->spe_status); | |
2975 | + T0_64 = u1.u; | |
2976 | + RETURN(); | |
2977 | +} | |
2978 | + | |
2979 | +void OPPROTO op_efdctsidz (void) | |
2980 | +{ | |
2981 | + do_efdctsiz(); | |
2982 | + RETURN(); | |
2983 | +} | |
2984 | + | |
2985 | +void OPPROTO op_efdctuidz (void) | |
2986 | +{ | |
2987 | + do_efdctuiz(); | |
2988 | + RETURN(); | |
2989 | +} | |
2990 | + | |
2991 | +void OPPROTO op_efdcmplt (void) | |
2992 | +{ | |
2993 | + do_efdcmplt(); | |
2994 | + RETURN(); | |
2995 | +} | |
2996 | + | |
2997 | +void OPPROTO op_efdcmpgt (void) | |
2998 | +{ | |
2999 | + do_efdcmpgt(); | |
3000 | + RETURN(); | |
3001 | +} | |
3002 | + | |
3003 | +void OPPROTO op_efdcfs (void) | |
3004 | +{ | |
3005 | + do_efdcfs(); | |
3006 | + RETURN(); | |
3007 | +} | |
3008 | + | |
3009 | +void OPPROTO op_efdcmpeq (void) | |
3010 | +{ | |
3011 | + do_efdcmpeq(); | |
3012 | + RETURN(); | |
3013 | +} | |
3014 | + | |
3015 | +void OPPROTO op_efdcfsi (void) | |
3016 | +{ | |
3017 | + do_efdcfsi(); | |
3018 | + RETURN(); | |
3019 | +} | |
3020 | + | |
3021 | +void OPPROTO op_efdcfui (void) | |
3022 | +{ | |
3023 | + do_efdcfui(); | |
3024 | + RETURN(); | |
3025 | +} | |
3026 | + | |
3027 | +void OPPROTO op_efdcfsf (void) | |
3028 | +{ | |
3029 | + do_efdcfsf(); | |
3030 | + RETURN(); | |
3031 | +} | |
3032 | + | |
3033 | +void OPPROTO op_efdcfuf (void) | |
3034 | +{ | |
3035 | + do_efdcfuf(); | |
3036 | + RETURN(); | |
3037 | +} | |
3038 | + | |
3039 | +void OPPROTO op_efdctsi (void) | |
3040 | +{ | |
3041 | + do_efdctsi(); | |
3042 | + RETURN(); | |
3043 | +} | |
3044 | + | |
3045 | +void OPPROTO op_efdctui (void) | |
3046 | +{ | |
3047 | + do_efdctui(); | |
3048 | + RETURN(); | |
3049 | +} | |
3050 | + | |
3051 | +void OPPROTO op_efdctsf (void) | |
3052 | +{ | |
3053 | + do_efdctsf(); | |
3054 | + RETURN(); | |
3055 | +} | |
3056 | + | |
3057 | +void OPPROTO op_efdctuf (void) | |
3058 | +{ | |
3059 | + do_efdctuf(); | |
3060 | + RETURN(); | |
3061 | +} | |
3062 | + | |
3063 | +void OPPROTO op_efdctuiz (void) | |
3064 | +{ | |
3065 | + do_efdctuiz(); | |
3066 | + RETURN(); | |
3067 | +} | |
3068 | + | |
3069 | +void OPPROTO op_efdctsiz (void) | |
3070 | +{ | |
3071 | + do_efdctsiz(); | |
3072 | + RETURN(); | |
3073 | +} | |
3074 | + | |
3075 | +void OPPROTO op_efdtstlt (void) | |
3076 | +{ | |
3077 | + T0 = _do_efdtstlt(T0_64, T1_64); | |
3078 | + RETURN(); | |
3079 | +} | |
3080 | + | |
3081 | +void OPPROTO op_efdtstgt (void) | |
3082 | +{ | |
3083 | + T0 = _do_efdtstgt(T0_64, T1_64); | |
3084 | + RETURN(); | |
3085 | +} | |
3086 | + | |
3087 | +void OPPROTO op_efdtsteq (void) | |
3088 | +{ | |
3089 | + T0 = _do_efdtsteq(T0_64, T1_64); | |
3090 | + RETURN(); | |
3091 | +} | |
3092 | +#endif /* defined(TARGET_PPCSPE) */ | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -19,12 +19,17 @@ |
19 | 19 | */ |
20 | 20 | #include "exec.h" |
21 | 21 | |
22 | +#include "op_helper.h" | |
23 | + | |
22 | 24 | #define MEMSUFFIX _raw |
25 | +#include "op_helper.h" | |
23 | 26 | #include "op_helper_mem.h" |
24 | 27 | #if !defined(CONFIG_USER_ONLY) |
25 | 28 | #define MEMSUFFIX _user |
29 | +#include "op_helper.h" | |
26 | 30 | #include "op_helper_mem.h" |
27 | 31 | #define MEMSUFFIX _kernel |
32 | +#include "op_helper.h" | |
28 | 33 | #include "op_helper_mem.h" |
29 | 34 | #endif |
30 | 35 | |
... | ... | @@ -229,7 +234,7 @@ void do_mul64 (uint64_t *plow, uint64_t *phigh) |
229 | 234 | mul64(plow, phigh, T0, T1); |
230 | 235 | } |
231 | 236 | |
232 | -static void imul64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b) | |
237 | +static void imul64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b) | |
233 | 238 | { |
234 | 239 | int sa, sb; |
235 | 240 | sa = (a < 0); |
... | ... | @@ -1119,6 +1124,868 @@ void do_440_dlmzb (void) |
1119 | 1124 | T0 = i; |
1120 | 1125 | } |
1121 | 1126 | |
1127 | +#if defined(TARGET_PPCSPE) | |
1128 | +/* SPE extension helpers */ | |
1129 | +/* Use a table to make this quicker */ | |
1130 | +static uint8_t hbrev[16] = { | |
1131 | + 0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, | |
1132 | + 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF, | |
1133 | +}; | |
1134 | + | |
1135 | +static inline uint8_t byte_reverse (uint8_t val) | |
1136 | +{ | |
1137 | + return hbrev[val >> 4] | (hbrev[val & 0xF] << 4); | |
1138 | +} | |
1139 | + | |
1140 | +static inline uint32_t word_reverse (uint32_t val) | |
1141 | +{ | |
1142 | + return byte_reverse(val >> 24) | (byte_reverse(val >> 16) << 8) | | |
1143 | + (byte_reverse(val >> 8) << 16) | (byte_reverse(val) << 24); | |
1144 | +} | |
1145 | + | |
1146 | +#define MASKBITS 16 // Random value - to be fixed | |
1147 | +void do_brinc (void) | |
1148 | +{ | |
1149 | + uint32_t a, b, d, mask; | |
1150 | + | |
1151 | + mask = (uint32_t)(-1UL) >> MASKBITS; | |
1152 | + b = T1_64 & mask; | |
1153 | + a = T0_64 & mask; | |
1154 | + d = word_reverse(1 + word_reverse(a | ~mask)); | |
1155 | + T0_64 = (T0_64 & ~mask) | (d & mask); | |
1156 | +} | |
1157 | + | |
1158 | +#define DO_SPE_OP2(name) \ | |
1159 | +void do_ev##name (void) \ | |
1160 | +{ \ | |
1161 | + T0_64 = ((uint64_t)_do_e##name(T0_64 >> 32, T1_64 >> 32) << 32) | \ | |
1162 | + (uint64_t)_do_e##name(T0_64, T1_64); \ | |
1163 | +} | |
1164 | + | |
1165 | +#define DO_SPE_OP1(name) \ | |
1166 | +void do_ev##name (void) \ | |
1167 | +{ \ | |
1168 | + T0_64 = ((uint64_t)_do_e##name(T0_64 >> 32) << 32) | \ | |
1169 | + (uint64_t)_do_e##name(T0_64); \ | |
1170 | +} | |
1171 | + | |
1172 | +/* Fixed-point vector arithmetic */ | |
1173 | +static inline uint32_t _do_eabs (uint32_t val) | |
1174 | +{ | |
1175 | + if (val != 0x80000000) | |
1176 | + val &= ~0x80000000; | |
1177 | + | |
1178 | + return val; | |
1179 | +} | |
1180 | + | |
1181 | +static inline uint32_t _do_eaddw (uint32_t op1, uint32_t op2) | |
1182 | +{ | |
1183 | + return op1 + op2; | |
1184 | +} | |
1185 | + | |
1186 | +static inline int _do_ecntlsw (uint32_t val) | |
1187 | +{ | |
1188 | + if (val & 0x80000000) | |
1189 | + return _do_cntlzw(~val); | |
1190 | + else | |
1191 | + return _do_cntlzw(val); | |
1192 | +} | |
1193 | + | |
1194 | +static inline int _do_ecntlzw (uint32_t val) | |
1195 | +{ | |
1196 | + return _do_cntlzw(val); | |
1197 | +} | |
1198 | + | |
1199 | +static inline uint32_t _do_eneg (uint32_t val) | |
1200 | +{ | |
1201 | + if (val != 0x80000000) | |
1202 | + val ^= 0x80000000; | |
1203 | + | |
1204 | + return val; | |
1205 | +} | |
1206 | + | |
1207 | +static inline uint32_t _do_erlw (uint32_t op1, uint32_t op2) | |
1208 | +{ | |
1209 | + return rotl32(op1, op2); | |
1210 | +} | |
1211 | + | |
1212 | +static inline uint32_t _do_erndw (uint32_t val) | |
1213 | +{ | |
1214 | + return (val + 0x000080000000) & 0xFFFF0000; | |
1215 | +} | |
1216 | + | |
1217 | +static inline uint32_t _do_eslw (uint32_t op1, uint32_t op2) | |
1218 | +{ | |
1219 | + /* No error here: 6 bits are used */ | |
1220 | + return op1 << (op2 & 0x3F); | |
1221 | +} | |
1222 | + | |
1223 | +static inline int32_t _do_esrws (int32_t op1, uint32_t op2) | |
1224 | +{ | |
1225 | + /* No error here: 6 bits are used */ | |
1226 | + return op1 >> (op2 & 0x3F); | |
1227 | +} | |
1228 | + | |
1229 | +static inline uint32_t _do_esrwu (uint32_t op1, uint32_t op2) | |
1230 | +{ | |
1231 | + /* No error here: 6 bits are used */ | |
1232 | + return op1 >> (op2 & 0x3F); | |
1233 | +} | |
1234 | + | |
1235 | +static inline uint32_t _do_esubfw (uint32_t op1, uint32_t op2) | |
1236 | +{ | |
1237 | + return op2 - op1; | |
1238 | +} | |
1239 | + | |
1240 | +/* evabs */ | |
1241 | +DO_SPE_OP1(abs); | |
1242 | +/* evaddw */ | |
1243 | +DO_SPE_OP2(addw); | |
1244 | +/* evcntlsw */ | |
1245 | +DO_SPE_OP1(cntlsw); | |
1246 | +/* evcntlzw */ | |
1247 | +DO_SPE_OP1(cntlzw); | |
1248 | +/* evneg */ | |
1249 | +DO_SPE_OP1(neg); | |
1250 | +/* evrlw */ | |
1251 | +DO_SPE_OP2(rlw); | |
1252 | +/* evrnd */ | |
1253 | +DO_SPE_OP1(rndw); | |
1254 | +/* evslw */ | |
1255 | +DO_SPE_OP2(slw); | |
1256 | +/* evsrws */ | |
1257 | +DO_SPE_OP2(srws); | |
1258 | +/* evsrwu */ | |
1259 | +DO_SPE_OP2(srwu); | |
1260 | +/* evsubfw */ | |
1261 | +DO_SPE_OP2(subfw); | |
1262 | + | |
1263 | +/* evsel is a little bit more complicated... */ | |
1264 | +static inline uint32_t _do_esel (uint32_t op1, uint32_t op2, int n) | |
1265 | +{ | |
1266 | + if (n) | |
1267 | + return op1; | |
1268 | + else | |
1269 | + return op2; | |
1270 | +} | |
1271 | + | |
1272 | +void do_evsel (void) | |
1273 | +{ | |
1274 | + T0_64 = ((uint64_t)_do_esel(T0_64 >> 32, T1_64 >> 32, T0 >> 3) << 32) | | |
1275 | + (uint64_t)_do_esel(T0_64, T1_64, (T0 >> 2) & 1); | |
1276 | +} | |
1277 | + | |
1278 | +/* Fixed-point vector comparisons */ | |
1279 | +#define DO_SPE_CMP(name) \ | |
1280 | +void do_ev##name (void) \ | |
1281 | +{ \ | |
1282 | + T0 = _do_evcmp_merge((uint64_t)_do_e##name(T0_64 >> 32, \ | |
1283 | + T1_64 >> 32) << 32, \ | |
1284 | + _do_e##name(T0_64, T1_64)); \ | |
1285 | +} | |
1286 | + | |
1287 | +static inline uint32_t _do_evcmp_merge (int t0, int t1) | |
1288 | +{ | |
1289 | + return (t0 << 3) | (t1 << 2) | ((t0 | t1) << 1) | (t0 & t1); | |
1290 | +} | |
1291 | +static inline int _do_ecmpeq (uint32_t op1, uint32_t op2) | |
1292 | +{ | |
1293 | + return op1 == op2 ? 1 : 0; | |
1294 | +} | |
1295 | + | |
1296 | +static inline int _do_ecmpgts (int32_t op1, int32_t op2) | |
1297 | +{ | |
1298 | + return op1 > op2 ? 1 : 0; | |
1299 | +} | |
1300 | + | |
1301 | +static inline int _do_ecmpgtu (uint32_t op1, uint32_t op2) | |
1302 | +{ | |
1303 | + return op1 > op2 ? 1 : 0; | |
1304 | +} | |
1305 | + | |
1306 | +static inline int _do_ecmplts (int32_t op1, int32_t op2) | |
1307 | +{ | |
1308 | + return op1 < op2 ? 1 : 0; | |
1309 | +} | |
1310 | + | |
1311 | +static inline int _do_ecmpltu (uint32_t op1, uint32_t op2) | |
1312 | +{ | |
1313 | + return op1 < op2 ? 1 : 0; | |
1314 | +} | |
1315 | + | |
1316 | +/* evcmpeq */ | |
1317 | +DO_SPE_CMP(cmpeq); | |
1318 | +/* evcmpgts */ | |
1319 | +DO_SPE_CMP(cmpgts); | |
1320 | +/* evcmpgtu */ | |
1321 | +DO_SPE_CMP(cmpgtu); | |
1322 | +/* evcmplts */ | |
1323 | +DO_SPE_CMP(cmplts); | |
1324 | +/* evcmpltu */ | |
1325 | +DO_SPE_CMP(cmpltu); | |
1326 | + | |
1327 | +/* Single precision floating-point conversions from/to integer */ | |
1328 | +static inline uint32_t _do_efscfsi (int32_t val) | |
1329 | +{ | |
1330 | + union { | |
1331 | + uint32_t u; | |
1332 | + float32 f; | |
1333 | + } u; | |
1334 | + | |
1335 | + u.f = int32_to_float32(val, &env->spe_status); | |
1336 | + | |
1337 | + return u.u; | |
1338 | +} | |
1339 | + | |
1340 | +static inline uint32_t _do_efscfui (uint32_t val) | |
1341 | +{ | |
1342 | + union { | |
1343 | + uint32_t u; | |
1344 | + float32 f; | |
1345 | + } u; | |
1346 | + | |
1347 | + u.f = uint32_to_float32(val, &env->spe_status); | |
1348 | + | |
1349 | + return u.u; | |
1350 | +} | |
1351 | + | |
1352 | +static inline int32_t _do_efsctsi (uint32_t val) | |
1353 | +{ | |
1354 | + union { | |
1355 | + int32_t u; | |
1356 | + float32 f; | |
1357 | + } u; | |
1358 | + | |
1359 | + u.u = val; | |
1360 | + /* NaN are not treated the same way IEEE 754 does */ | |
1361 | + if (unlikely(isnan(u.f))) | |
1362 | + return 0; | |
1363 | + | |
1364 | + return float32_to_int32(u.f, &env->spe_status); | |
1365 | +} | |
1366 | + | |
1367 | +static inline uint32_t _do_efsctui (uint32_t val) | |
1368 | +{ | |
1369 | + union { | |
1370 | + int32_t u; | |
1371 | + float32 f; | |
1372 | + } u; | |
1373 | + | |
1374 | + u.u = val; | |
1375 | + /* NaN are not treated the same way IEEE 754 does */ | |
1376 | + if (unlikely(isnan(u.f))) | |
1377 | + return 0; | |
1378 | + | |
1379 | + return float32_to_uint32(u.f, &env->spe_status); | |
1380 | +} | |
1381 | + | |
1382 | +static inline int32_t _do_efsctsiz (uint32_t val) | |
1383 | +{ | |
1384 | + union { | |
1385 | + int32_t u; | |
1386 | + float32 f; | |
1387 | + } u; | |
1388 | + | |
1389 | + u.u = val; | |
1390 | + /* NaN are not treated the same way IEEE 754 does */ | |
1391 | + if (unlikely(isnan(u.f))) | |
1392 | + return 0; | |
1393 | + | |
1394 | + return float32_to_int32_round_to_zero(u.f, &env->spe_status); | |
1395 | +} | |
1396 | + | |
1397 | +static inline uint32_t _do_efsctuiz (uint32_t val) | |
1398 | +{ | |
1399 | + union { | |
1400 | + int32_t u; | |
1401 | + float32 f; | |
1402 | + } u; | |
1403 | + | |
1404 | + u.u = val; | |
1405 | + /* NaN are not treated the same way IEEE 754 does */ | |
1406 | + if (unlikely(isnan(u.f))) | |
1407 | + return 0; | |
1408 | + | |
1409 | + return float32_to_uint32_round_to_zero(u.f, &env->spe_status); | |
1410 | +} | |
1411 | + | |
1412 | +void do_efscfsi (void) | |
1413 | +{ | |
1414 | + T0_64 = _do_efscfsi(T0_64); | |
1415 | +} | |
1416 | + | |
1417 | +void do_efscfui (void) | |
1418 | +{ | |
1419 | + T0_64 = _do_efscfui(T0_64); | |
1420 | +} | |
1421 | + | |
1422 | +void do_efsctsi (void) | |
1423 | +{ | |
1424 | + T0_64 = _do_efsctsi(T0_64); | |
1425 | +} | |
1426 | + | |
1427 | +void do_efsctui (void) | |
1428 | +{ | |
1429 | + T0_64 = _do_efsctui(T0_64); | |
1430 | +} | |
1431 | + | |
1432 | +void do_efsctsiz (void) | |
1433 | +{ | |
1434 | + T0_64 = _do_efsctsiz(T0_64); | |
1435 | +} | |
1436 | + | |
1437 | +void do_efsctuiz (void) | |
1438 | +{ | |
1439 | + T0_64 = _do_efsctuiz(T0_64); | |
1440 | +} | |
1441 | + | |
1442 | +/* Single precision floating-point conversion to/from fractional */ | |
1443 | +static inline uint32_t _do_efscfsf (uint32_t val) | |
1444 | +{ | |
1445 | + union { | |
1446 | + uint32_t u; | |
1447 | + float32 f; | |
1448 | + } u; | |
1449 | + float32 tmp; | |
1450 | + | |
1451 | + u.f = int32_to_float32(val, &env->spe_status); | |
1452 | + tmp = int64_to_float32(1ULL << 32, &env->spe_status); | |
1453 | + u.f = float32_div(u.f, tmp, &env->spe_status); | |
1454 | + | |
1455 | + return u.u; | |
1456 | +} | |
1457 | + | |
1458 | +static inline uint32_t _do_efscfuf (uint32_t val) | |
1459 | +{ | |
1460 | + union { | |
1461 | + uint32_t u; | |
1462 | + float32 f; | |
1463 | + } u; | |
1464 | + float32 tmp; | |
1465 | + | |
1466 | + u.f = uint32_to_float32(val, &env->spe_status); | |
1467 | + tmp = uint64_to_float32(1ULL << 32, &env->spe_status); | |
1468 | + u.f = float32_div(u.f, tmp, &env->spe_status); | |
1469 | + | |
1470 | + return u.u; | |
1471 | +} | |
1472 | + | |
1473 | +static inline int32_t _do_efsctsf (uint32_t val) | |
1474 | +{ | |
1475 | + union { | |
1476 | + int32_t u; | |
1477 | + float32 f; | |
1478 | + } u; | |
1479 | + float32 tmp; | |
1480 | + | |
1481 | + u.u = val; | |
1482 | + /* NaN are not treated the same way IEEE 754 does */ | |
1483 | + if (unlikely(isnan(u.f))) | |
1484 | + return 0; | |
1485 | + tmp = uint64_to_float32(1ULL << 32, &env->spe_status); | |
1486 | + u.f = float32_mul(u.f, tmp, &env->spe_status); | |
1487 | + | |
1488 | + return float32_to_int32(u.f, &env->spe_status); | |
1489 | +} | |
1490 | + | |
1491 | +static inline uint32_t _do_efsctuf (uint32_t val) | |
1492 | +{ | |
1493 | + union { | |
1494 | + int32_t u; | |
1495 | + float32 f; | |
1496 | + } u; | |
1497 | + float32 tmp; | |
1498 | + | |
1499 | + u.u = val; | |
1500 | + /* NaN are not treated the same way IEEE 754 does */ | |
1501 | + if (unlikely(isnan(u.f))) | |
1502 | + return 0; | |
1503 | + tmp = uint64_to_float32(1ULL << 32, &env->spe_status); | |
1504 | + u.f = float32_mul(u.f, tmp, &env->spe_status); | |
1505 | + | |
1506 | + return float32_to_uint32(u.f, &env->spe_status); | |
1507 | +} | |
1508 | + | |
1509 | +static inline int32_t _do_efsctsfz (uint32_t val) | |
1510 | +{ | |
1511 | + union { | |
1512 | + int32_t u; | |
1513 | + float32 f; | |
1514 | + } u; | |
1515 | + float32 tmp; | |
1516 | + | |
1517 | + u.u = val; | |
1518 | + /* NaN are not treated the same way IEEE 754 does */ | |
1519 | + if (unlikely(isnan(u.f))) | |
1520 | + return 0; | |
1521 | + tmp = uint64_to_float32(1ULL << 32, &env->spe_status); | |
1522 | + u.f = float32_mul(u.f, tmp, &env->spe_status); | |
1523 | + | |
1524 | + return float32_to_int32_round_to_zero(u.f, &env->spe_status); | |
1525 | +} | |
1526 | + | |
1527 | +static inline uint32_t _do_efsctufz (uint32_t val) | |
1528 | +{ | |
1529 | + union { | |
1530 | + int32_t u; | |
1531 | + float32 f; | |
1532 | + } u; | |
1533 | + float32 tmp; | |
1534 | + | |
1535 | + u.u = val; | |
1536 | + /* NaN are not treated the same way IEEE 754 does */ | |
1537 | + if (unlikely(isnan(u.f))) | |
1538 | + return 0; | |
1539 | + tmp = uint64_to_float32(1ULL << 32, &env->spe_status); | |
1540 | + u.f = float32_mul(u.f, tmp, &env->spe_status); | |
1541 | + | |
1542 | + return float32_to_uint32_round_to_zero(u.f, &env->spe_status); | |
1543 | +} | |
1544 | + | |
1545 | +void do_efscfsf (void) | |
1546 | +{ | |
1547 | + T0_64 = _do_efscfsf(T0_64); | |
1548 | +} | |
1549 | + | |
1550 | +void do_efscfuf (void) | |
1551 | +{ | |
1552 | + T0_64 = _do_efscfuf(T0_64); | |
1553 | +} | |
1554 | + | |
1555 | +void do_efsctsf (void) | |
1556 | +{ | |
1557 | + T0_64 = _do_efsctsf(T0_64); | |
1558 | +} | |
1559 | + | |
1560 | +void do_efsctuf (void) | |
1561 | +{ | |
1562 | + T0_64 = _do_efsctuf(T0_64); | |
1563 | +} | |
1564 | + | |
1565 | +void do_efsctsfz (void) | |
1566 | +{ | |
1567 | + T0_64 = _do_efsctsfz(T0_64); | |
1568 | +} | |
1569 | + | |
1570 | +void do_efsctufz (void) | |
1571 | +{ | |
1572 | + T0_64 = _do_efsctufz(T0_64); | |
1573 | +} | |
1574 | + | |
1575 | +/* Double precision floating point helpers */ | |
1576 | +static inline int _do_efdcmplt (uint64_t op1, uint64_t op2) | |
1577 | +{ | |
1578 | + /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
1579 | + return _do_efdtstlt(op1, op2); | |
1580 | +} | |
1581 | + | |
1582 | +static inline int _do_efdcmpgt (uint64_t op1, uint64_t op2) | |
1583 | +{ | |
1584 | + /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
1585 | + return _do_efdtstgt(op1, op2); | |
1586 | +} | |
1587 | + | |
1588 | +static inline int _do_efdcmpeq (uint64_t op1, uint64_t op2) | |
1589 | +{ | |
1590 | + /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
1591 | + return _do_efdtsteq(op1, op2); | |
1592 | +} | |
1593 | + | |
1594 | +void do_efdcmplt (void) | |
1595 | +{ | |
1596 | + T0 = _do_efdcmplt(T0_64, T1_64); | |
1597 | +} | |
1598 | + | |
1599 | +void do_efdcmpgt (void) | |
1600 | +{ | |
1601 | + T0 = _do_efdcmpgt(T0_64, T1_64); | |
1602 | +} | |
1603 | + | |
1604 | +void do_efdcmpeq (void) | |
1605 | +{ | |
1606 | + T0 = _do_efdcmpeq(T0_64, T1_64); | |
1607 | +} | |
1608 | + | |
1609 | +/* Double precision floating-point conversion to/from integer */ | |
1610 | +static inline uint64_t _do_efdcfsi (int64_t val) | |
1611 | +{ | |
1612 | + union { | |
1613 | + uint64_t u; | |
1614 | + float64 f; | |
1615 | + } u; | |
1616 | + | |
1617 | + u.f = int64_to_float64(val, &env->spe_status); | |
1618 | + | |
1619 | + return u.u; | |
1620 | +} | |
1621 | + | |
1622 | +static inline uint64_t _do_efdcfui (uint64_t val) | |
1623 | +{ | |
1624 | + union { | |
1625 | + uint64_t u; | |
1626 | + float64 f; | |
1627 | + } u; | |
1628 | + | |
1629 | + u.f = uint64_to_float64(val, &env->spe_status); | |
1630 | + | |
1631 | + return u.u; | |
1632 | +} | |
1633 | + | |
1634 | +static inline int64_t _do_efdctsi (uint64_t val) | |
1635 | +{ | |
1636 | + union { | |
1637 | + int64_t u; | |
1638 | + float64 f; | |
1639 | + } u; | |
1640 | + | |
1641 | + u.u = val; | |
1642 | + /* NaN are not treated the same way IEEE 754 does */ | |
1643 | + if (unlikely(isnan(u.f))) | |
1644 | + return 0; | |
1645 | + | |
1646 | + return float64_to_int64(u.f, &env->spe_status); | |
1647 | +} | |
1648 | + | |
1649 | +static inline uint64_t _do_efdctui (uint64_t val) | |
1650 | +{ | |
1651 | + union { | |
1652 | + int64_t u; | |
1653 | + float64 f; | |
1654 | + } u; | |
1655 | + | |
1656 | + u.u = val; | |
1657 | + /* NaN are not treated the same way IEEE 754 does */ | |
1658 | + if (unlikely(isnan(u.f))) | |
1659 | + return 0; | |
1660 | + | |
1661 | + return float64_to_uint64(u.f, &env->spe_status); | |
1662 | +} | |
1663 | + | |
1664 | +static inline int64_t _do_efdctsiz (uint64_t val) | |
1665 | +{ | |
1666 | + union { | |
1667 | + int64_t u; | |
1668 | + float64 f; | |
1669 | + } u; | |
1670 | + | |
1671 | + u.u = val; | |
1672 | + /* NaN are not treated the same way IEEE 754 does */ | |
1673 | + if (unlikely(isnan(u.f))) | |
1674 | + return 0; | |
1675 | + | |
1676 | + return float64_to_int64_round_to_zero(u.f, &env->spe_status); | |
1677 | +} | |
1678 | + | |
1679 | +static inline uint64_t _do_efdctuiz (uint64_t val) | |
1680 | +{ | |
1681 | + union { | |
1682 | + int64_t u; | |
1683 | + float64 f; | |
1684 | + } u; | |
1685 | + | |
1686 | + u.u = val; | |
1687 | + /* NaN are not treated the same way IEEE 754 does */ | |
1688 | + if (unlikely(isnan(u.f))) | |
1689 | + return 0; | |
1690 | + | |
1691 | + return float64_to_uint64_round_to_zero(u.f, &env->spe_status); | |
1692 | +} | |
1693 | + | |
1694 | +void do_efdcfsi (void) | |
1695 | +{ | |
1696 | + T0_64 = _do_efdcfsi(T0_64); | |
1697 | +} | |
1698 | + | |
1699 | +void do_efdcfui (void) | |
1700 | +{ | |
1701 | + T0_64 = _do_efdcfui(T0_64); | |
1702 | +} | |
1703 | + | |
1704 | +void do_efdctsi (void) | |
1705 | +{ | |
1706 | + T0_64 = _do_efdctsi(T0_64); | |
1707 | +} | |
1708 | + | |
1709 | +void do_efdctui (void) | |
1710 | +{ | |
1711 | + T0_64 = _do_efdctui(T0_64); | |
1712 | +} | |
1713 | + | |
1714 | +void do_efdctsiz (void) | |
1715 | +{ | |
1716 | + T0_64 = _do_efdctsiz(T0_64); | |
1717 | +} | |
1718 | + | |
1719 | +void do_efdctuiz (void) | |
1720 | +{ | |
1721 | + T0_64 = _do_efdctuiz(T0_64); | |
1722 | +} | |
1723 | + | |
1724 | +/* Double precision floating-point conversion to/from fractional */ | |
1725 | +static inline uint64_t _do_efdcfsf (int64_t val) | |
1726 | +{ | |
1727 | + union { | |
1728 | + uint64_t u; | |
1729 | + float64 f; | |
1730 | + } u; | |
1731 | + float64 tmp; | |
1732 | + | |
1733 | + u.f = int32_to_float64(val, &env->spe_status); | |
1734 | + tmp = int64_to_float64(1ULL << 32, &env->spe_status); | |
1735 | + u.f = float64_div(u.f, tmp, &env->spe_status); | |
1736 | + | |
1737 | + return u.u; | |
1738 | +} | |
1739 | + | |
1740 | +static inline uint64_t _do_efdcfuf (uint64_t val) | |
1741 | +{ | |
1742 | + union { | |
1743 | + uint64_t u; | |
1744 | + float64 f; | |
1745 | + } u; | |
1746 | + float64 tmp; | |
1747 | + | |
1748 | + u.f = uint32_to_float64(val, &env->spe_status); | |
1749 | + tmp = int64_to_float64(1ULL << 32, &env->spe_status); | |
1750 | + u.f = float64_div(u.f, tmp, &env->spe_status); | |
1751 | + | |
1752 | + return u.u; | |
1753 | +} | |
1754 | + | |
1755 | +static inline int64_t _do_efdctsf (uint64_t val) | |
1756 | +{ | |
1757 | + union { | |
1758 | + int64_t u; | |
1759 | + float64 f; | |
1760 | + } u; | |
1761 | + float64 tmp; | |
1762 | + | |
1763 | + u.u = val; | |
1764 | + /* NaN are not treated the same way IEEE 754 does */ | |
1765 | + if (unlikely(isnan(u.f))) | |
1766 | + return 0; | |
1767 | + tmp = uint64_to_float64(1ULL << 32, &env->spe_status); | |
1768 | + u.f = float64_mul(u.f, tmp, &env->spe_status); | |
1769 | + | |
1770 | + return float64_to_int32(u.f, &env->spe_status); | |
1771 | +} | |
1772 | + | |
1773 | +static inline uint64_t _do_efdctuf (uint64_t val) | |
1774 | +{ | |
1775 | + union { | |
1776 | + int64_t u; | |
1777 | + float64 f; | |
1778 | + } u; | |
1779 | + float64 tmp; | |
1780 | + | |
1781 | + u.u = val; | |
1782 | + /* NaN are not treated the same way IEEE 754 does */ | |
1783 | + if (unlikely(isnan(u.f))) | |
1784 | + return 0; | |
1785 | + tmp = uint64_to_float64(1ULL << 32, &env->spe_status); | |
1786 | + u.f = float64_mul(u.f, tmp, &env->spe_status); | |
1787 | + | |
1788 | + return float64_to_uint32(u.f, &env->spe_status); | |
1789 | +} | |
1790 | + | |
1791 | +static inline int64_t _do_efdctsfz (uint64_t val) | |
1792 | +{ | |
1793 | + union { | |
1794 | + int64_t u; | |
1795 | + float64 f; | |
1796 | + } u; | |
1797 | + float64 tmp; | |
1798 | + | |
1799 | + u.u = val; | |
1800 | + /* NaN are not treated the same way IEEE 754 does */ | |
1801 | + if (unlikely(isnan(u.f))) | |
1802 | + return 0; | |
1803 | + tmp = uint64_to_float64(1ULL << 32, &env->spe_status); | |
1804 | + u.f = float64_mul(u.f, tmp, &env->spe_status); | |
1805 | + | |
1806 | + return float64_to_int32_round_to_zero(u.f, &env->spe_status); | |
1807 | +} | |
1808 | + | |
1809 | +static inline uint64_t _do_efdctufz (uint64_t val) | |
1810 | +{ | |
1811 | + union { | |
1812 | + int64_t u; | |
1813 | + float64 f; | |
1814 | + } u; | |
1815 | + float64 tmp; | |
1816 | + | |
1817 | + u.u = val; | |
1818 | + /* NaN are not treated the same way IEEE 754 does */ | |
1819 | + if (unlikely(isnan(u.f))) | |
1820 | + return 0; | |
1821 | + tmp = uint64_to_float64(1ULL << 32, &env->spe_status); | |
1822 | + u.f = float64_mul(u.f, tmp, &env->spe_status); | |
1823 | + | |
1824 | + return float64_to_uint32_round_to_zero(u.f, &env->spe_status); | |
1825 | +} | |
1826 | + | |
1827 | +void do_efdcfsf (void) | |
1828 | +{ | |
1829 | + T0_64 = _do_efdcfsf(T0_64); | |
1830 | +} | |
1831 | + | |
1832 | +void do_efdcfuf (void) | |
1833 | +{ | |
1834 | + T0_64 = _do_efdcfuf(T0_64); | |
1835 | +} | |
1836 | + | |
1837 | +void do_efdctsf (void) | |
1838 | +{ | |
1839 | + T0_64 = _do_efdctsf(T0_64); | |
1840 | +} | |
1841 | + | |
1842 | +void do_efdctuf (void) | |
1843 | +{ | |
1844 | + T0_64 = _do_efdctuf(T0_64); | |
1845 | +} | |
1846 | + | |
1847 | +void do_efdctsfz (void) | |
1848 | +{ | |
1849 | + T0_64 = _do_efdctsfz(T0_64); | |
1850 | +} | |
1851 | + | |
1852 | +void do_efdctufz (void) | |
1853 | +{ | |
1854 | + T0_64 = _do_efdctufz(T0_64); | |
1855 | +} | |
1856 | + | |
1857 | +/* Floating point conversion between single and double precision */ | |
1858 | +static inline uint32_t _do_efscfd (uint64_t val) | |
1859 | +{ | |
1860 | + union { | |
1861 | + uint64_t u; | |
1862 | + float64 f; | |
1863 | + } u1; | |
1864 | + union { | |
1865 | + uint32_t u; | |
1866 | + float32 f; | |
1867 | + } u2; | |
1868 | + | |
1869 | + u1.u = val; | |
1870 | + u2.f = float64_to_float32(u1.f, &env->spe_status); | |
1871 | + | |
1872 | + return u2.u; | |
1873 | +} | |
1874 | + | |
1875 | +static inline uint64_t _do_efdcfs (uint32_t val) | |
1876 | +{ | |
1877 | + union { | |
1878 | + uint64_t u; | |
1879 | + float64 f; | |
1880 | + } u2; | |
1881 | + union { | |
1882 | + uint32_t u; | |
1883 | + float32 f; | |
1884 | + } u1; | |
1885 | + | |
1886 | + u1.u = val; | |
1887 | + u2.f = float32_to_float64(u1.f, &env->spe_status); | |
1888 | + | |
1889 | + return u2.u; | |
1890 | +} | |
1891 | + | |
1892 | +void do_efscfd (void) | |
1893 | +{ | |
1894 | + T0_64 = _do_efscfd(T0_64); | |
1895 | +} | |
1896 | + | |
1897 | +void do_efdcfs (void) | |
1898 | +{ | |
1899 | + T0_64 = _do_efdcfs(T0_64); | |
1900 | +} | |
1901 | + | |
1902 | +/* Single precision fixed-point vector arithmetic */ | |
1903 | +/* evfsabs */ | |
1904 | +DO_SPE_OP1(fsabs); | |
1905 | +/* evfsnabs */ | |
1906 | +DO_SPE_OP1(fsnabs); | |
1907 | +/* evfsneg */ | |
1908 | +DO_SPE_OP1(fsneg); | |
1909 | +/* evfsadd */ | |
1910 | +DO_SPE_OP2(fsadd); | |
1911 | +/* evfssub */ | |
1912 | +DO_SPE_OP2(fssub); | |
1913 | +/* evfsmul */ | |
1914 | +DO_SPE_OP2(fsmul); | |
1915 | +/* evfsdiv */ | |
1916 | +DO_SPE_OP2(fsdiv); | |
1917 | + | |
1918 | +/* Single-precision floating-point comparisons */ | |
1919 | +static inline int _do_efscmplt (uint32_t op1, uint32_t op2) | |
1920 | +{ | |
1921 | + /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
1922 | + return _do_efststlt(op1, op2); | |
1923 | +} | |
1924 | + | |
1925 | +static inline int _do_efscmpgt (uint32_t op1, uint32_t op2) | |
1926 | +{ | |
1927 | + /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
1928 | + return _do_efststgt(op1, op2); | |
1929 | +} | |
1930 | + | |
1931 | +static inline int _do_efscmpeq (uint32_t op1, uint32_t op2) | |
1932 | +{ | |
1933 | + /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
1934 | + return _do_efststeq(op1, op2); | |
1935 | +} | |
1936 | + | |
1937 | +void do_efscmplt (void) | |
1938 | +{ | |
1939 | + T0 = _do_efscmplt(T0_64, T1_64); | |
1940 | +} | |
1941 | + | |
1942 | +void do_efscmpgt (void) | |
1943 | +{ | |
1944 | + T0 = _do_efscmpgt(T0_64, T1_64); | |
1945 | +} | |
1946 | + | |
1947 | +void do_efscmpeq (void) | |
1948 | +{ | |
1949 | + T0 = _do_efscmpeq(T0_64, T1_64); | |
1950 | +} | |
1951 | + | |
1952 | +/* Single-precision floating-point vector comparisons */ | |
1953 | +/* evfscmplt */ | |
1954 | +DO_SPE_CMP(fscmplt); | |
1955 | +/* evfscmpgt */ | |
1956 | +DO_SPE_CMP(fscmpgt); | |
1957 | +/* evfscmpeq */ | |
1958 | +DO_SPE_CMP(fscmpeq); | |
1959 | +/* evfststlt */ | |
1960 | +DO_SPE_CMP(fststlt); | |
1961 | +/* evfststgt */ | |
1962 | +DO_SPE_CMP(fststgt); | |
1963 | +/* evfststeq */ | |
1964 | +DO_SPE_CMP(fststeq); | |
1965 | + | |
1966 | +/* Single-precision floating-point vector conversions */ | |
1967 | +/* evfscfsi */ | |
1968 | +DO_SPE_OP1(fscfsi); | |
1969 | +/* evfscfui */ | |
1970 | +DO_SPE_OP1(fscfui); | |
1971 | +/* evfscfuf */ | |
1972 | +DO_SPE_OP1(fscfuf); | |
1973 | +/* evfscfsf */ | |
1974 | +DO_SPE_OP1(fscfsf); | |
1975 | +/* evfsctsi */ | |
1976 | +DO_SPE_OP1(fsctsi); | |
1977 | +/* evfsctui */ | |
1978 | +DO_SPE_OP1(fsctui); | |
1979 | +/* evfsctsiz */ | |
1980 | +DO_SPE_OP1(fsctsiz); | |
1981 | +/* evfsctuiz */ | |
1982 | +DO_SPE_OP1(fsctuiz); | |
1983 | +/* evfsctsf */ | |
1984 | +DO_SPE_OP1(fsctsf); | |
1985 | +/* evfsctuf */ | |
1986 | +DO_SPE_OP1(fsctuf); | |
1987 | +#endif /* defined(TARGET_PPCSPE) */ | |
1988 | + | |
1122 | 1989 | /*****************************************************************************/ |
1123 | 1990 | /* Softmmu support */ |
1124 | 1991 | #if !defined (CONFIG_USER_ONLY) | ... | ... |
target-ppc/op_helper.h
... | ... | @@ -100,6 +100,7 @@ void do_fctiwz (void); |
100 | 100 | void do_fcmpu (void); |
101 | 101 | void do_fcmpo (void); |
102 | 102 | |
103 | +/* Misc */ | |
103 | 104 | void do_tw (int flags); |
104 | 105 | #if defined(TARGET_PPC64) |
105 | 106 | void do_td (int flags); |
... | ... | @@ -157,11 +158,291 @@ void do_4xx_tlbwe_lo (void); |
157 | 158 | void do_4xx_tlbwe_hi (void); |
158 | 159 | #endif |
159 | 160 | |
161 | +/* PowerPC 440 specific helpers */ | |
160 | 162 | void do_440_dlmzb (void); |
161 | 163 | |
164 | +/* PowerPC 403 specific helpers */ | |
162 | 165 | #if !defined(CONFIG_USER_ONLY) |
163 | 166 | void do_load_403_pb (int num); |
164 | 167 | void do_store_403_pb (int num); |
165 | 168 | #endif |
166 | 169 | |
170 | +#if defined(TARGET_PPCSPE) | |
171 | +/* SPE extension helpers */ | |
172 | +void do_brinc (void); | |
173 | +/* Fixed-point vector helpers */ | |
174 | +void do_evabs (void); | |
175 | +void do_evaddw (void); | |
176 | +void do_evcntlsw (void); | |
177 | +void do_evcntlzw (void); | |
178 | +void do_evneg (void); | |
179 | +void do_evrlw (void); | |
180 | +void do_evsel (void); | |
181 | +void do_evrndw (void); | |
182 | +void do_evslw (void); | |
183 | +void do_evsrws (void); | |
184 | +void do_evsrwu (void); | |
185 | +void do_evsubfw (void); | |
186 | +void do_evcmpeq (void); | |
187 | +void do_evcmpgts (void); | |
188 | +void do_evcmpgtu (void); | |
189 | +void do_evcmplts (void); | |
190 | +void do_evcmpltu (void); | |
191 | + | |
192 | +/* Single precision floating-point helpers */ | |
193 | +void do_efscmplt (void); | |
194 | +void do_efscmpgt (void); | |
195 | +void do_efscmpeq (void); | |
196 | +void do_efscfsf (void); | |
197 | +void do_efscfuf (void); | |
198 | +void do_efsctsf (void); | |
199 | +void do_efsctuf (void); | |
200 | + | |
201 | +void do_efscfsi (void); | |
202 | +void do_efscfui (void); | |
203 | +void do_efsctsi (void); | |
204 | +void do_efsctui (void); | |
205 | +void do_efsctsiz (void); | |
206 | +void do_efsctuiz (void); | |
207 | + | |
208 | +/* Double precision floating-point helpers */ | |
209 | +void do_efdcmplt (void); | |
210 | +void do_efdcmpgt (void); | |
211 | +void do_efdcmpeq (void); | |
212 | +void do_efdcfsf (void); | |
213 | +void do_efdcfuf (void); | |
214 | +void do_efdctsf (void); | |
215 | +void do_efdctuf (void); | |
216 | + | |
217 | +void do_efdcfsi (void); | |
218 | +void do_efdcfui (void); | |
219 | +void do_efdctsi (void); | |
220 | +void do_efdctui (void); | |
221 | +void do_efdctsiz (void); | |
222 | +void do_efdctuiz (void); | |
223 | + | |
224 | +void do_efdcfs (void); | |
225 | +void do_efscfd (void); | |
226 | + | |
227 | +/* Floating-point vector helpers */ | |
228 | +void do_evfsabs (void); | |
229 | +void do_evfsnabs (void); | |
230 | +void do_evfsneg (void); | |
231 | +void do_evfsadd (void); | |
232 | +void do_evfssub (void); | |
233 | +void do_evfsmul (void); | |
234 | +void do_evfsdiv (void); | |
235 | +void do_evfscmplt (void); | |
236 | +void do_evfscmpgt (void); | |
237 | +void do_evfscmpeq (void); | |
238 | +void do_evfststlt (void); | |
239 | +void do_evfststgt (void); | |
240 | +void do_evfststeq (void); | |
241 | +void do_evfscfsi (void); | |
242 | +void do_evfscfui (void); | |
243 | +void do_evfscfsf (void); | |
244 | +void do_evfscfuf (void); | |
245 | +void do_evfsctsf (void); | |
246 | +void do_evfsctuf (void); | |
247 | +void do_evfsctsi (void); | |
248 | +void do_evfsctui (void); | |
249 | +void do_evfsctsiz (void); | |
250 | +void do_evfsctuiz (void); | |
251 | +#endif /* defined(TARGET_PPCSPE) */ | |
252 | + | |
253 | +/* Inlined helpers: used in micro-operation as well as helpers */ | |
254 | +/* Generic fixed-point helpers */ | |
255 | +static inline int _do_cntlzw (uint32_t val) | |
256 | +{ | |
257 | + int cnt = 0; | |
258 | + if (!(val & 0xFFFF0000UL)) { | |
259 | + cnt += 16; | |
260 | + val <<= 16; | |
261 | + } | |
262 | + if (!(val & 0xFF000000UL)) { | |
263 | + cnt += 8; | |
264 | + val <<= 8; | |
265 | + } | |
266 | + if (!(val & 0xF0000000UL)) { | |
267 | + cnt += 4; | |
268 | + val <<= 4; | |
269 | + } | |
270 | + if (!(val & 0xC0000000UL)) { | |
271 | + cnt += 2; | |
272 | + val <<= 2; | |
273 | + } | |
274 | + if (!(val & 0x80000000UL)) { | |
275 | + cnt++; | |
276 | + val <<= 1; | |
277 | + } | |
278 | + if (!(val & 0x80000000UL)) { | |
279 | + cnt++; | |
280 | + } | |
281 | + return cnt; | |
282 | +} | |
283 | + | |
284 | +static inline int _do_cntlzd (uint64_t val) | |
285 | +{ | |
286 | + int cnt = 0; | |
287 | +#if HOST_LONG_BITS == 64 | |
288 | + if (!(val & 0xFFFFFFFF00000000ULL)) { | |
289 | + cnt += 32; | |
290 | + val <<= 32; | |
291 | + } | |
292 | + if (!(val & 0xFFFF000000000000ULL)) { | |
293 | + cnt += 16; | |
294 | + val <<= 16; | |
295 | + } | |
296 | + if (!(val & 0xFF00000000000000ULL)) { | |
297 | + cnt += 8; | |
298 | + val <<= 8; | |
299 | + } | |
300 | + if (!(val & 0xF000000000000000ULL)) { | |
301 | + cnt += 4; | |
302 | + val <<= 4; | |
303 | + } | |
304 | + if (!(val & 0xC000000000000000ULL)) { | |
305 | + cnt += 2; | |
306 | + val <<= 2; | |
307 | + } | |
308 | + if (!(val & 0x8000000000000000ULL)) { | |
309 | + cnt++; | |
310 | + val <<= 1; | |
311 | + } | |
312 | + if (!(val & 0x8000000000000000ULL)) { | |
313 | + cnt++; | |
314 | + } | |
315 | +#else | |
316 | + uint32_t tmp; | |
317 | + /* Make it easier on 32 bits host machines */ | |
318 | + if (!(val >> 32)) | |
319 | + cnt = cntlzw(val) + 32; | |
320 | + else | |
321 | + cnt = cntlzw(val >> 32); | |
322 | +#endif | |
323 | + return cnt; | |
324 | +} | |
325 | + | |
326 | +#if defined(TARGET_PPCSPE) | |
327 | +/* SPE extension */ | |
328 | +/* Single precision floating-point helpers */ | |
329 | +static inline uint32_t _do_efsabs (uint32_t val) | |
330 | +{ | |
331 | + return val & ~0x80000000; | |
332 | +} | |
333 | +static inline uint32_t _do_efsnabs (uint32_t val) | |
334 | +{ | |
335 | + return val | 0x80000000; | |
336 | +} | |
337 | +static inline uint32_t _do_efsneg (uint32_t val) | |
338 | +{ | |
339 | + return val ^ 0x80000000; | |
340 | +} | |
341 | +static inline uint32_t _do_efsadd (uint32_t op1, uint32_t op2) | |
342 | +{ | |
343 | + union { | |
344 | + uint32_t u; | |
345 | + float32 f; | |
346 | + } u1, u2; | |
347 | + u1.u = op1; | |
348 | + u2.u = op2; | |
349 | + u1.f = float32_add(u1.f, u2.f, &env->spe_status); | |
350 | + return u1.u; | |
351 | +} | |
352 | +static inline uint32_t _do_efssub (uint32_t op1, uint32_t op2) | |
353 | +{ | |
354 | + union { | |
355 | + uint32_t u; | |
356 | + float32 f; | |
357 | + } u1, u2; | |
358 | + u1.u = op1; | |
359 | + u2.u = op2; | |
360 | + u1.f = float32_sub(u1.f, u2.f, &env->spe_status); | |
361 | + return u1.u; | |
362 | +} | |
363 | +static inline uint32_t _do_efsmul (uint32_t op1, uint32_t op2) | |
364 | +{ | |
365 | + union { | |
366 | + uint32_t u; | |
367 | + float32 f; | |
368 | + } u1, u2; | |
369 | + u1.u = op1; | |
370 | + u2.u = op2; | |
371 | + u1.f = float32_mul(u1.f, u2.f, &env->spe_status); | |
372 | + return u1.u; | |
373 | +} | |
374 | +static inline uint32_t _do_efsdiv (uint32_t op1, uint32_t op2) | |
375 | +{ | |
376 | + union { | |
377 | + uint32_t u; | |
378 | + float32 f; | |
379 | + } u1, u2; | |
380 | + u1.u = op1; | |
381 | + u2.u = op2; | |
382 | + u1.f = float32_div(u1.f, u2.f, &env->spe_status); | |
383 | + return u1.u; | |
384 | +} | |
385 | + | |
386 | +static inline int _do_efststlt (uint32_t op1, uint32_t op2) | |
387 | +{ | |
388 | + union { | |
389 | + uint32_t u; | |
390 | + float32 f; | |
391 | + } u1, u2; | |
392 | + u1.u = op1; | |
393 | + u2.u = op2; | |
394 | + return float32_lt(u1.f, u2.f, &env->spe_status) ? 1 : 0; | |
395 | +} | |
396 | +static inline int _do_efststgt (uint32_t op1, uint32_t op2) | |
397 | +{ | |
398 | + union { | |
399 | + uint32_t u; | |
400 | + float32 f; | |
401 | + } u1, u2; | |
402 | + u1.u = op1; | |
403 | + u2.u = op2; | |
404 | + return float32_le(u1.f, u2.f, &env->spe_status) ? 0 : 1; | |
405 | +} | |
406 | +static inline int _do_efststeq (uint32_t op1, uint32_t op2) | |
407 | +{ | |
408 | + union { | |
409 | + uint32_t u; | |
410 | + float32 f; | |
411 | + } u1, u2; | |
412 | + u1.u = op1; | |
413 | + u2.u = op2; | |
414 | + return float32_eq(u1.f, u2.f, &env->spe_status) ? 1 : 0; | |
415 | +} | |
416 | +/* Double precision floating-point helpers */ | |
417 | +static inline int _do_efdtstlt (uint64_t op1, uint64_t op2) | |
418 | +{ | |
419 | + union { | |
420 | + uint64_t u; | |
421 | + float64 f; | |
422 | + } u1, u2; | |
423 | + u1.u = op1; | |
424 | + u2.u = op2; | |
425 | + return float64_lt(u1.f, u2.f, &env->spe_status) ? 1 : 0; | |
426 | +} | |
427 | +static inline int _do_efdtstgt (uint64_t op1, uint64_t op2) | |
428 | +{ | |
429 | + union { | |
430 | + uint64_t u; | |
431 | + float64 f; | |
432 | + } u1, u2; | |
433 | + u1.u = op1; | |
434 | + u2.u = op2; | |
435 | + return float64_le(u1.f, u2.f, &env->spe_status) ? 0 : 1; | |
436 | +} | |
437 | +static inline int _do_efdtsteq (uint64_t op1, uint64_t op2) | |
438 | +{ | |
439 | + union { | |
440 | + uint64_t u; | |
441 | + float64 f; | |
442 | + } u1, u2; | |
443 | + u1.u = op1; | |
444 | + u2.u = op2; | |
445 | + return float64_eq(u1.f, u2.f, &env->spe_status) ? 1 : 0; | |
446 | +} | |
447 | +#endif /* defined(TARGET_PPCSPE) */ | |
167 | 448 | #endif | ... | ... |
target-ppc/op_mem.h
... | ... | @@ -37,12 +37,7 @@ static inline uint32_t glue(ld32r, MEMSUFFIX) (target_ulong EA) |
37 | 37 | ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24); |
38 | 38 | } |
39 | 39 | |
40 | -#if defined(TARGET_PPC64) | |
41 | -static inline int64_t glue(ldsl, MEMSUFFIX) (target_ulong EA) | |
42 | -{ | |
43 | - return (int32_t)glue(ldl, MEMSUFFIX)(EA); | |
44 | -} | |
45 | - | |
40 | +#if defined(TARGET_PPC64) || defined(TARGET_PPCSPE) | |
46 | 41 | static inline uint64_t glue(ld64r, MEMSUFFIX) (target_ulong EA) |
47 | 42 | { |
48 | 43 | uint64_t tmp = glue(ldq, MEMSUFFIX)(EA); |
... | ... | @@ -55,6 +50,13 @@ static inline uint64_t glue(ld64r, MEMSUFFIX) (target_ulong EA) |
55 | 50 | ((tmp & 0x000000000000FF00ULL) << 40) | |
56 | 51 | ((tmp & 0x00000000000000FFULL) << 54); |
57 | 52 | } |
53 | +#endif | |
54 | + | |
55 | +#if defined(TARGET_PPC64) | |
56 | +static inline int64_t glue(ldsl, MEMSUFFIX) (target_ulong EA) | |
57 | +{ | |
58 | + return (int32_t)glue(ldl, MEMSUFFIX)(EA); | |
59 | +} | |
58 | 60 | |
59 | 61 | static inline int64_t glue(ld32rs, MEMSUFFIX) (target_ulong EA) |
60 | 62 | { |
... | ... | @@ -77,7 +79,7 @@ static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, uint32_t data) |
77 | 79 | glue(stl, MEMSUFFIX)(EA, tmp); |
78 | 80 | } |
79 | 81 | |
80 | -#if defined(TARGET_PPC64) | |
82 | +#if defined(TARGET_PPC64) || defined(TARGET_PPCSPE) | |
81 | 83 | static inline void glue(st64r, MEMSUFFIX) (target_ulong EA, uint64_t data) |
82 | 84 | { |
83 | 85 | uint64_t tmp = ((data & 0xFF00000000000000ULL) >> 56) | |
... | ... | @@ -839,4 +841,262 @@ void OPPROTO glue(op_POWER2_stfq_le, MEMSUFFIX) (void) |
839 | 841 | RETURN(); |
840 | 842 | } |
841 | 843 | |
844 | +#if defined(TARGET_PPCSPE) | |
845 | +/* SPE extension */ | |
846 | +#define _PPC_SPE_LD_OP(name, op) \ | |
847 | +void OPPROTO glue(glue(op_spe_l, name), MEMSUFFIX) (void) \ | |
848 | +{ \ | |
849 | + T1_64 = glue(op, MEMSUFFIX)((uint32_t)T0); \ | |
850 | + RETURN(); \ | |
851 | +} | |
852 | + | |
853 | +#if defined(TARGET_PPC64) | |
854 | +#define _PPC_SPE_LD_OP_64(name, op) \ | |
855 | +void OPPROTO glue(glue(glue(op_spe_l, name), _64), MEMSUFFIX) (void) \ | |
856 | +{ \ | |
857 | + T1_64 = glue(op, MEMSUFFIX)((uint64_t)T0); \ | |
858 | + RETURN(); \ | |
859 | +} | |
860 | +#define PPC_SPE_LD_OP(name, op) \ | |
861 | +_PPC_SPE_LD_OP(name, op); \ | |
862 | +_PPC_SPE_LD_OP_64(name, op) | |
863 | +#else | |
864 | +#define PPC_SPE_LD_OP(name, op) \ | |
865 | +_PPC_SPE_LD_OP(name, op) | |
866 | +#endif | |
867 | + | |
868 | + | |
869 | +#define _PPC_SPE_ST_OP(name, op) \ | |
870 | +void OPPROTO glue(glue(op_spe_st, name), MEMSUFFIX) (void) \ | |
871 | +{ \ | |
872 | + glue(op, MEMSUFFIX)((uint32_t)T0, T1_64); \ | |
873 | + RETURN(); \ | |
874 | +} | |
875 | + | |
876 | +#if defined(TARGET_PPC64) | |
877 | +#define _PPC_SPE_ST_OP_64(name, op) \ | |
878 | +void OPPROTO glue(glue(glue(op_spe_st, name), _64), MEMSUFFIX) (void) \ | |
879 | +{ \ | |
880 | + glue(op, MEMSUFFIX)((uint64_t)T0, T1_64); \ | |
881 | + RETURN(); \ | |
882 | +} | |
883 | +#define PPC_SPE_ST_OP(name, op) \ | |
884 | +_PPC_SPE_ST_OP(name, op); \ | |
885 | +_PPC_SPE_ST_OP_64(name, op) | |
886 | +#else | |
887 | +#define PPC_SPE_ST_OP(name, op) \ | |
888 | +_PPC_SPE_ST_OP(name, op) | |
889 | +#endif | |
890 | + | |
891 | +#if !defined(TARGET_PPC64) | |
892 | +PPC_SPE_LD_OP(dd, ldq); | |
893 | +PPC_SPE_ST_OP(dd, stq); | |
894 | +PPC_SPE_LD_OP(dd_le, ld64r); | |
895 | +PPC_SPE_ST_OP(dd_le, st64r); | |
896 | +#endif | |
897 | +static inline uint64_t glue(spe_ldw, MEMSUFFIX) (target_ulong EA) | |
898 | +{ | |
899 | + uint64_t ret; | |
900 | + ret = (uint64_t)glue(ldl, MEMSUFFIX)(EA) << 32; | |
901 | + ret |= (uint64_t)glue(ldl, MEMSUFFIX)(EA + 4); | |
902 | + return ret; | |
903 | +} | |
904 | +PPC_SPE_LD_OP(dw, spe_ldw); | |
905 | +static inline void glue(spe_stdw, MEMSUFFIX) (target_ulong EA, uint64_t data) | |
906 | +{ | |
907 | + glue(stl, MEMSUFFIX)(EA, data >> 32); | |
908 | + glue(stl, MEMSUFFIX)(EA + 4, data); | |
909 | +} | |
910 | +PPC_SPE_ST_OP(dw, spe_stdw); | |
911 | +static inline uint64_t glue(spe_ldw_le, MEMSUFFIX) (target_ulong EA) | |
912 | +{ | |
913 | + uint64_t ret; | |
914 | + ret = (uint64_t)glue(ld32r, MEMSUFFIX)(EA) << 32; | |
915 | + ret |= (uint64_t)glue(ld32r, MEMSUFFIX)(EA + 4); | |
916 | + return ret; | |
917 | +} | |
918 | +PPC_SPE_LD_OP(dw_le, spe_ldw_le); | |
919 | +static inline void glue(spe_stdw_le, MEMSUFFIX) (target_ulong EA, | |
920 | + uint64_t data) | |
921 | +{ | |
922 | + glue(st32r, MEMSUFFIX)(EA, data >> 32); | |
923 | + glue(st32r, MEMSUFFIX)(EA + 4, data); | |
924 | +} | |
925 | +PPC_SPE_ST_OP(dw_le, spe_stdw_le); | |
926 | +static inline uint64_t glue(spe_ldh, MEMSUFFIX) (target_ulong EA) | |
927 | +{ | |
928 | + uint64_t ret; | |
929 | + ret = (uint64_t)glue(lduw, MEMSUFFIX)(EA) << 48; | |
930 | + ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 2) << 32; | |
931 | + ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 4) << 16; | |
932 | + ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 6); | |
933 | + return ret; | |
934 | +} | |
935 | +PPC_SPE_LD_OP(dh, spe_ldh); | |
936 | +static inline void glue(spe_stdh, MEMSUFFIX) (target_ulong EA, uint64_t data) | |
937 | +{ | |
938 | + glue(stw, MEMSUFFIX)(EA, data >> 48); | |
939 | + glue(stw, MEMSUFFIX)(EA + 2, data >> 32); | |
940 | + glue(stw, MEMSUFFIX)(EA + 4, data >> 16); | |
941 | + glue(stw, MEMSUFFIX)(EA + 6, data); | |
942 | +} | |
943 | +PPC_SPE_ST_OP(dh, spe_stdh); | |
944 | +static inline uint64_t glue(spe_ldh_le, MEMSUFFIX) (target_ulong EA) | |
945 | +{ | |
946 | + uint64_t ret; | |
947 | + ret = (uint64_t)glue(ld16r, MEMSUFFIX)(EA) << 48; | |
948 | + ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 2) << 32; | |
949 | + ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 4) << 16; | |
950 | + ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 6); | |
951 | + return ret; | |
952 | +} | |
953 | +PPC_SPE_LD_OP(dh_le, spe_ldh_le); | |
954 | +static inline void glue(spe_stdh_le, MEMSUFFIX) (target_ulong EA, | |
955 | + uint64_t data) | |
956 | +{ | |
957 | + glue(st16r, MEMSUFFIX)(EA, data >> 48); | |
958 | + glue(st16r, MEMSUFFIX)(EA + 2, data >> 32); | |
959 | + glue(st16r, MEMSUFFIX)(EA + 4, data >> 16); | |
960 | + glue(st16r, MEMSUFFIX)(EA + 6, data); | |
961 | +} | |
962 | +PPC_SPE_ST_OP(dh_le, spe_stdh_le); | |
963 | +static inline uint64_t glue(spe_lwhe, MEMSUFFIX) (target_ulong EA) | |
964 | +{ | |
965 | + uint64_t ret; | |
966 | + ret = (uint64_t)glue(lduw, MEMSUFFIX)(EA) << 48; | |
967 | + ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 2) << 16; | |
968 | + return ret; | |
969 | +} | |
970 | +PPC_SPE_LD_OP(whe, spe_lwhe); | |
971 | +static inline void glue(spe_stwhe, MEMSUFFIX) (target_ulong EA, uint64_t data) | |
972 | +{ | |
973 | + glue(stw, MEMSUFFIX)(EA, data >> 48); | |
974 | + glue(stw, MEMSUFFIX)(EA + 2, data >> 16); | |
975 | +} | |
976 | +PPC_SPE_ST_OP(whe, spe_stwhe); | |
977 | +static inline uint64_t glue(spe_lwhe_le, MEMSUFFIX) (target_ulong EA) | |
978 | +{ | |
979 | + uint64_t ret; | |
980 | + ret = (uint64_t)glue(ld16r, MEMSUFFIX)(EA) << 48; | |
981 | + ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 2) << 16; | |
982 | + return ret; | |
983 | +} | |
984 | +PPC_SPE_LD_OP(whe_le, spe_lwhe_le); | |
985 | +static inline void glue(spe_stwhe_le, MEMSUFFIX) (target_ulong EA, | |
986 | + uint64_t data) | |
987 | +{ | |
988 | + glue(st16r, MEMSUFFIX)(EA, data >> 48); | |
989 | + glue(st16r, MEMSUFFIX)(EA + 2, data >> 16); | |
990 | +} | |
991 | +PPC_SPE_ST_OP(whe_le, spe_stwhe_le); | |
992 | +static inline uint64_t glue(spe_lwhou, MEMSUFFIX) (target_ulong EA) | |
993 | +{ | |
994 | + uint64_t ret; | |
995 | + ret = (uint64_t)glue(lduw, MEMSUFFIX)(EA) << 32; | |
996 | + ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 2); | |
997 | + return ret; | |
998 | +} | |
999 | +PPC_SPE_LD_OP(whou, spe_lwhou); | |
1000 | +static inline uint64_t glue(spe_lwhos, MEMSUFFIX) (target_ulong EA) | |
1001 | +{ | |
1002 | + uint64_t ret; | |
1003 | + ret = ((uint64_t)((int32_t)glue(ldsw, MEMSUFFIX)(EA))) << 32; | |
1004 | + ret |= (uint64_t)((int32_t)glue(ldsw, MEMSUFFIX)(EA + 2)); | |
1005 | + return ret; | |
1006 | +} | |
1007 | +PPC_SPE_LD_OP(whos, spe_lwhos); | |
1008 | +static inline void glue(spe_stwho, MEMSUFFIX) (target_ulong EA, uint64_t data) | |
1009 | +{ | |
1010 | + glue(stw, MEMSUFFIX)(EA, data >> 32); | |
1011 | + glue(stw, MEMSUFFIX)(EA + 2, data); | |
1012 | +} | |
1013 | +PPC_SPE_ST_OP(who, spe_stwho); | |
1014 | +static inline uint64_t glue(spe_lwhou_le, MEMSUFFIX) (target_ulong EA) | |
1015 | +{ | |
1016 | + uint64_t ret; | |
1017 | + ret = (uint64_t)glue(ld16r, MEMSUFFIX)(EA) << 32; | |
1018 | + ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 2); | |
1019 | + return ret; | |
1020 | +} | |
1021 | +PPC_SPE_LD_OP(whou_le, spe_lwhou_le); | |
1022 | +static inline uint64_t glue(spe_lwhos_le, MEMSUFFIX) (target_ulong EA) | |
1023 | +{ | |
1024 | + uint64_t ret; | |
1025 | + ret = ((uint64_t)((int32_t)glue(ld16rs, MEMSUFFIX)(EA))) << 32; | |
1026 | + ret |= (uint64_t)((int32_t)glue(ld16rs, MEMSUFFIX)(EA + 2)); | |
1027 | + return ret; | |
1028 | +} | |
1029 | +PPC_SPE_LD_OP(whos_le, spe_lwhos_le); | |
1030 | +static inline void glue(spe_stwho_le, MEMSUFFIX) (target_ulong EA, | |
1031 | + uint64_t data) | |
1032 | +{ | |
1033 | + glue(st16r, MEMSUFFIX)(EA, data >> 32); | |
1034 | + glue(st16r, MEMSUFFIX)(EA + 2, data); | |
1035 | +} | |
1036 | +PPC_SPE_ST_OP(who_le, spe_stwho_le); | |
1037 | +#if !defined(TARGET_PPC64) | |
1038 | +static inline void glue(spe_stwwo, MEMSUFFIX) (target_ulong EA, uint64_t data) | |
1039 | +{ | |
1040 | + glue(stl, MEMSUFFIX)(EA, data); | |
1041 | +} | |
1042 | +PPC_SPE_ST_OP(wwo, spe_stwwo); | |
1043 | +static inline void glue(spe_stwwo_le, MEMSUFFIX) (target_ulong EA, | |
1044 | + uint64_t data) | |
1045 | +{ | |
1046 | + glue(st32r, MEMSUFFIX)(EA, data); | |
1047 | +} | |
1048 | +PPC_SPE_ST_OP(wwo_le, spe_stwwo_le); | |
1049 | +#endif | |
1050 | +static inline uint64_t glue(spe_lh, MEMSUFFIX) (target_ulong EA) | |
1051 | +{ | |
1052 | + uint16_t tmp; | |
1053 | + tmp = glue(lduw, MEMSUFFIX)(EA); | |
1054 | + return ((uint64_t)tmp << 48) | ((uint64_t)tmp << 16); | |
1055 | +} | |
1056 | +PPC_SPE_LD_OP(h, spe_lh); | |
1057 | +static inline uint64_t glue(spe_lh_le, MEMSUFFIX) (target_ulong EA) | |
1058 | +{ | |
1059 | + uint16_t tmp; | |
1060 | + tmp = glue(ld16r, MEMSUFFIX)(EA); | |
1061 | + return ((uint64_t)tmp << 48) | ((uint64_t)tmp << 16); | |
1062 | +} | |
1063 | +PPC_SPE_LD_OP(h_le, spe_lh_le); | |
1064 | +static inline uint64_t glue(spe_lwwsplat, MEMSUFFIX) (target_ulong EA) | |
1065 | +{ | |
1066 | + uint32_t tmp; | |
1067 | + tmp = glue(ldl, MEMSUFFIX)(EA); | |
1068 | + return ((uint64_t)tmp << 32) | (uint64_t)tmp; | |
1069 | +} | |
1070 | +PPC_SPE_LD_OP(wwsplat, spe_lwwsplat); | |
1071 | +static inline uint64_t glue(spe_lwwsplat_le, MEMSUFFIX) (target_ulong EA) | |
1072 | +{ | |
1073 | + uint32_t tmp; | |
1074 | + tmp = glue(ld32r, MEMSUFFIX)(EA); | |
1075 | + return ((uint64_t)tmp << 32) | (uint64_t)tmp; | |
1076 | +} | |
1077 | +PPC_SPE_LD_OP(wwsplat_le, spe_lwwsplat_le); | |
1078 | +static inline uint64_t glue(spe_lwhsplat, MEMSUFFIX) (target_ulong EA) | |
1079 | +{ | |
1080 | + uint64_t ret; | |
1081 | + uint16_t tmp; | |
1082 | + tmp = glue(lduw, MEMSUFFIX)(EA); | |
1083 | + ret = ((uint64_t)tmp << 48) | ((uint64_t)tmp << 32); | |
1084 | + tmp = glue(lduw, MEMSUFFIX)(EA + 2); | |
1085 | + ret |= ((uint64_t)tmp << 16) | (uint64_t)tmp; | |
1086 | + return ret; | |
1087 | +} | |
1088 | +PPC_SPE_LD_OP(whsplat, spe_lwhsplat); | |
1089 | +static inline uint64_t glue(spe_lwhsplat_le, MEMSUFFIX) (target_ulong EA) | |
1090 | +{ | |
1091 | + uint64_t ret; | |
1092 | + uint16_t tmp; | |
1093 | + tmp = glue(ld16r, MEMSUFFIX)(EA); | |
1094 | + ret = ((uint64_t)tmp << 48) | ((uint64_t)tmp << 32); | |
1095 | + tmp = glue(ld16r, MEMSUFFIX)(EA + 2); | |
1096 | + ret |= ((uint64_t)tmp << 16) | (uint64_t)tmp; | |
1097 | + return ret; | |
1098 | +} | |
1099 | +PPC_SPE_LD_OP(whsplat_le, spe_lwhsplat_le); | |
1100 | +#endif /* defined(TARGET_PPCSPE) */ | |
1101 | + | |
842 | 1102 | #undef MEMSUFFIX | ... | ... |
target-ppc/op_template.h
... | ... | @@ -57,6 +57,48 @@ void OPPROTO glue(op_store_T2_gpr_gpr, REG) (void) |
57 | 57 | } |
58 | 58 | #endif |
59 | 59 | |
60 | +#if defined(TARGET_PPCSPE) | |
61 | +void OPPROTO glue(op_load_gpr64_T0_gpr, REG) (void) | |
62 | +{ | |
63 | + T0_64 = regs->gpr[REG]; | |
64 | + RETURN(); | |
65 | +} | |
66 | + | |
67 | +void OPPROTO glue(op_load_gpr64_T1_gpr, REG) (void) | |
68 | +{ | |
69 | + T1_64 = regs->gpr[REG]; | |
70 | + RETURN(); | |
71 | +} | |
72 | + | |
73 | +#if 0 // unused | |
74 | +void OPPROTO glue(op_load_gpr64_T2_gpr, REG) (void) | |
75 | +{ | |
76 | + T2_64 = regs->gpr[REG]; | |
77 | + RETURN(); | |
78 | +} | |
79 | +#endif | |
80 | + | |
81 | +void OPPROTO glue(op_store_T0_gpr64_gpr, REG) (void) | |
82 | +{ | |
83 | + regs->gpr[REG] = T0_64; | |
84 | + RETURN(); | |
85 | +} | |
86 | + | |
87 | +void OPPROTO glue(op_store_T1_gpr64_gpr, REG) (void) | |
88 | +{ | |
89 | + regs->gpr[REG] = T1_64; | |
90 | + RETURN(); | |
91 | +} | |
92 | + | |
93 | +#if 0 // unused | |
94 | +void OPPROTO glue(op_store_T2_gpr64_gpr, REG) (void) | |
95 | +{ | |
96 | + regs->gpr[REG] = T2_64; | |
97 | + RETURN(); | |
98 | +} | |
99 | +#endif | |
100 | +#endif /* defined(TARGET_PPCSPE) */ | |
101 | + | |
60 | 102 | #if REG <= 7 |
61 | 103 | /* Condition register moves */ |
62 | 104 | void OPPROTO glue(op_load_crf_T0_crf, REG) (void) | ... | ... |
target-ppc/translate.c
... | ... | @@ -160,6 +160,9 @@ typedef struct DisasContext { |
160 | 160 | int sf_mode; |
161 | 161 | #endif |
162 | 162 | int fpu_enabled; |
163 | +#if defined(TARGET_PPCSPE) | |
164 | + int spe_enabled; | |
165 | +#endif | |
163 | 166 | ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ |
164 | 167 | int singlestep_enabled; |
165 | 168 | } DisasContext; |
... | ... | @@ -168,7 +171,7 @@ struct opc_handler_t { |
168 | 171 | /* invalid bits */ |
169 | 172 | uint32_t inval; |
170 | 173 | /* instruction type */ |
171 | - uint32_t type; | |
174 | + uint64_t type; | |
172 | 175 | /* handler */ |
173 | 176 | void (*handler)(DisasContext *ctx); |
174 | 177 | #if defined(DO_PPC_STATISTICS) |
... | ... | @@ -4468,6 +4471,814 @@ GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE) |
4468 | 4471 | */ |
4469 | 4472 | } |
4470 | 4473 | |
4474 | +#if defined(TARGET_PPCSPE) | |
4475 | +/*** SPE extension ***/ | |
4476 | + | |
4477 | +/* Register moves */ | |
4478 | +GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr); | |
4479 | +GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr); | |
4480 | +#if 0 // unused | |
4481 | +GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr); | |
4482 | +#endif | |
4483 | + | |
4484 | +GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr); | |
4485 | +GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr); | |
4486 | +#if 0 // unused | |
4487 | +GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr); | |
4488 | +#endif | |
4489 | + | |
4490 | +#define GEN_SPE(name0, name1, opc2, opc3, inval, type) \ | |
4491 | +GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type) \ | |
4492 | +{ \ | |
4493 | + if (Rc(ctx->opcode)) \ | |
4494 | + gen_##name1(ctx); \ | |
4495 | + else \ | |
4496 | + gen_##name0(ctx); \ | |
4497 | +} | |
4498 | + | |
4499 | +/* Handler for undefined SPE opcodes */ | |
4500 | +static inline void gen_speundef (DisasContext *ctx) | |
4501 | +{ | |
4502 | + RET_INVAL(ctx); | |
4503 | +} | |
4504 | + | |
4505 | +/* SPE load and stores */ | |
4506 | +static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh) | |
4507 | +{ | |
4508 | + target_long simm = rB(ctx->opcode); | |
4509 | + | |
4510 | + if (rA(ctx->opcode) == 0) { | |
4511 | + gen_set_T0(simm << sh); | |
4512 | + } else { | |
4513 | + gen_op_load_gpr_T0(rA(ctx->opcode)); | |
4514 | + if (likely(simm != 0)) | |
4515 | + gen_op_addi(simm << sh); | |
4516 | + } | |
4517 | +} | |
4518 | + | |
4519 | +#define op_spe_ldst(name) (*gen_op_##name[ctx->mem_idx])() | |
4520 | +#if defined(CONFIG_USER_ONLY) | |
4521 | +#if defined(TARGET_PPC64) | |
4522 | +#define OP_SPE_LD_TABLE(name) \ | |
4523 | +static GenOpFunc *gen_op_spe_l##name[] = { \ | |
4524 | + &gen_op_spe_l##name##_raw, \ | |
4525 | + &gen_op_spe_l##name##_le_raw, \ | |
4526 | + &gen_op_spe_l##name##_64_raw, \ | |
4527 | + &gen_op_spe_l##name##_le_64_raw, \ | |
4528 | +}; | |
4529 | +#define OP_SPE_ST_TABLE(name) \ | |
4530 | +static GenOpFunc *gen_op_spe_st##name[] = { \ | |
4531 | + &gen_op_spe_st##name##_raw, \ | |
4532 | + &gen_op_spe_st##name##_le_raw, \ | |
4533 | + &gen_op_spe_st##name##_64_raw, \ | |
4534 | + &gen_op_spe_st##name##_le_64_raw, \ | |
4535 | +}; | |
4536 | +#else /* defined(TARGET_PPC64) */ | |
4537 | +#define OP_SPE_LD_TABLE(name) \ | |
4538 | +static GenOpFunc *gen_op_spe_l##name[] = { \ | |
4539 | + &gen_op_spe_l##name##_raw, \ | |
4540 | + &gen_op_spe_l##name##_le_raw, \ | |
4541 | +}; | |
4542 | +#define OP_SPE_ST_TABLE(name) \ | |
4543 | +static GenOpFunc *gen_op_spe_st##name[] = { \ | |
4544 | + &gen_op_spe_st##name##_raw, \ | |
4545 | + &gen_op_spe_st##name##_le_raw, \ | |
4546 | +}; | |
4547 | +#endif /* defined(TARGET_PPC64) */ | |
4548 | +#else /* defined(CONFIG_USER_ONLY) */ | |
4549 | +#if defined(TARGET_PPC64) | |
4550 | +#define OP_SPE_LD_TABLE(name) \ | |
4551 | +static GenOpFunc *gen_op_spe_l##name[] = { \ | |
4552 | + &gen_op_spe_l##name##_user, \ | |
4553 | + &gen_op_spe_l##name##_le_user, \ | |
4554 | + &gen_op_spe_l##name##_kernel, \ | |
4555 | + &gen_op_spe_l##name##_le_kernel, \ | |
4556 | + &gen_op_spe_l##name##_64_user, \ | |
4557 | + &gen_op_spe_l##name##_le_64_user, \ | |
4558 | + &gen_op_spe_l##name##_64_kernel, \ | |
4559 | + &gen_op_spe_l##name##_le_64_kernel, \ | |
4560 | +}; | |
4561 | +#define OP_SPE_ST_TABLE(name) \ | |
4562 | +static GenOpFunc *gen_op_spe_st##name[] = { \ | |
4563 | + &gen_op_spe_st##name##_user, \ | |
4564 | + &gen_op_spe_st##name##_le_user, \ | |
4565 | + &gen_op_spe_st##name##_kernel, \ | |
4566 | + &gen_op_spe_st##name##_le_kernel, \ | |
4567 | + &gen_op_spe_st##name##_64_user, \ | |
4568 | + &gen_op_spe_st##name##_le_64_user, \ | |
4569 | + &gen_op_spe_st##name##_64_kernel, \ | |
4570 | + &gen_op_spe_st##name##_le_64_kernel, \ | |
4571 | +}; | |
4572 | +#else /* defined(TARGET_PPC64) */ | |
4573 | +#define OP_SPE_LD_TABLE(name) \ | |
4574 | +static GenOpFunc *gen_op_spe_l##name[] = { \ | |
4575 | + &gen_op_spe_l##name##_user, \ | |
4576 | + &gen_op_spe_l##name##_le_user, \ | |
4577 | + &gen_op_spe_l##name##_kernel, \ | |
4578 | + &gen_op_spe_l##name##_le_kernel, \ | |
4579 | +}; | |
4580 | +#define OP_SPE_ST_TABLE(name) \ | |
4581 | +static GenOpFunc *gen_op_spe_st##name[] = { \ | |
4582 | + &gen_op_spe_st##name##_user, \ | |
4583 | + &gen_op_spe_st##name##_le_user, \ | |
4584 | + &gen_op_spe_st##name##_kernel, \ | |
4585 | + &gen_op_spe_st##name##_le_kernel, \ | |
4586 | +}; | |
4587 | +#endif /* defined(TARGET_PPC64) */ | |
4588 | +#endif /* defined(CONFIG_USER_ONLY) */ | |
4589 | + | |
4590 | +#define GEN_SPE_LD(name, sh) \ | |
4591 | +static inline void gen_evl##name (DisasContext *ctx) \ | |
4592 | +{ \ | |
4593 | + if (unlikely(!ctx->spe_enabled)) { \ | |
4594 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); \ | |
4595 | + return; \ | |
4596 | + } \ | |
4597 | + gen_addr_spe_imm_index(ctx, sh); \ | |
4598 | + op_spe_ldst(spe_l##name); \ | |
4599 | + gen_op_store_T1_gpr64(rD(ctx->opcode)); \ | |
4600 | +} | |
4601 | + | |
4602 | +#define GEN_SPE_LDX(name) \ | |
4603 | +static inline void gen_evl##name##x (DisasContext *ctx) \ | |
4604 | +{ \ | |
4605 | + if (unlikely(!ctx->spe_enabled)) { \ | |
4606 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); \ | |
4607 | + return; \ | |
4608 | + } \ | |
4609 | + gen_addr_reg_index(ctx); \ | |
4610 | + op_spe_ldst(spe_l##name); \ | |
4611 | + gen_op_store_T1_gpr64(rD(ctx->opcode)); \ | |
4612 | +} | |
4613 | + | |
4614 | +#define GEN_SPEOP_LD(name, sh) \ | |
4615 | +OP_SPE_LD_TABLE(name); \ | |
4616 | +GEN_SPE_LD(name, sh); \ | |
4617 | +GEN_SPE_LDX(name) | |
4618 | + | |
4619 | +#define GEN_SPE_ST(name, sh) \ | |
4620 | +static inline void gen_evst##name (DisasContext *ctx) \ | |
4621 | +{ \ | |
4622 | + if (unlikely(!ctx->spe_enabled)) { \ | |
4623 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); \ | |
4624 | + return; \ | |
4625 | + } \ | |
4626 | + gen_addr_spe_imm_index(ctx, sh); \ | |
4627 | + gen_op_load_gpr64_T1(rS(ctx->opcode)); \ | |
4628 | + op_spe_ldst(spe_st##name); \ | |
4629 | +} | |
4630 | + | |
4631 | +#define GEN_SPE_STX(name) \ | |
4632 | +static inline void gen_evst##name##x (DisasContext *ctx) \ | |
4633 | +{ \ | |
4634 | + if (unlikely(!ctx->spe_enabled)) { \ | |
4635 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); \ | |
4636 | + return; \ | |
4637 | + } \ | |
4638 | + gen_addr_reg_index(ctx); \ | |
4639 | + gen_op_load_gpr64_T1(rS(ctx->opcode)); \ | |
4640 | + op_spe_ldst(spe_st##name); \ | |
4641 | +} | |
4642 | + | |
4643 | +#define GEN_SPEOP_ST(name, sh) \ | |
4644 | +OP_SPE_ST_TABLE(name); \ | |
4645 | +GEN_SPE_ST(name, sh); \ | |
4646 | +GEN_SPE_STX(name) | |
4647 | + | |
4648 | +#define GEN_SPEOP_LDST(name, sh) \ | |
4649 | +GEN_SPEOP_LD(name, sh); \ | |
4650 | +GEN_SPEOP_ST(name, sh) | |
4651 | + | |
4652 | +/* SPE arithmetic and logic */ | |
4653 | +#define GEN_SPEOP_ARITH2(name) \ | |
4654 | +static inline void gen_##name (DisasContext *ctx) \ | |
4655 | +{ \ | |
4656 | + if (unlikely(!ctx->spe_enabled)) { \ | |
4657 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); \ | |
4658 | + return; \ | |
4659 | + } \ | |
4660 | + gen_op_load_gpr64_T0(rA(ctx->opcode)); \ | |
4661 | + gen_op_load_gpr64_T1(rB(ctx->opcode)); \ | |
4662 | + gen_op_##name(); \ | |
4663 | + gen_op_store_T0_gpr64(rD(ctx->opcode)); \ | |
4664 | +} | |
4665 | + | |
4666 | +#define GEN_SPEOP_ARITH1(name) \ | |
4667 | +static inline void gen_##name (DisasContext *ctx) \ | |
4668 | +{ \ | |
4669 | + if (unlikely(!ctx->spe_enabled)) { \ | |
4670 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); \ | |
4671 | + return; \ | |
4672 | + } \ | |
4673 | + gen_op_load_gpr64_T0(rA(ctx->opcode)); \ | |
4674 | + gen_op_##name(); \ | |
4675 | + gen_op_store_T0_gpr64(rD(ctx->opcode)); \ | |
4676 | +} | |
4677 | + | |
4678 | +#define GEN_SPEOP_COMP(name) \ | |
4679 | +static inline void gen_##name (DisasContext *ctx) \ | |
4680 | +{ \ | |
4681 | + if (unlikely(!ctx->spe_enabled)) { \ | |
4682 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); \ | |
4683 | + return; \ | |
4684 | + } \ | |
4685 | + gen_op_load_gpr64_T0(rA(ctx->opcode)); \ | |
4686 | + gen_op_load_gpr64_T1(rB(ctx->opcode)); \ | |
4687 | + gen_op_##name(); \ | |
4688 | + gen_op_store_T0_crf(crfD(ctx->opcode)); \ | |
4689 | +} | |
4690 | + | |
4691 | +/* Logical */ | |
4692 | +GEN_SPEOP_ARITH2(evand); | |
4693 | +GEN_SPEOP_ARITH2(evandc); | |
4694 | +GEN_SPEOP_ARITH2(evxor); | |
4695 | +GEN_SPEOP_ARITH2(evor); | |
4696 | +GEN_SPEOP_ARITH2(evnor); | |
4697 | +GEN_SPEOP_ARITH2(eveqv); | |
4698 | +GEN_SPEOP_ARITH2(evorc); | |
4699 | +GEN_SPEOP_ARITH2(evnand); | |
4700 | +GEN_SPEOP_ARITH2(evsrwu); | |
4701 | +GEN_SPEOP_ARITH2(evsrws); | |
4702 | +GEN_SPEOP_ARITH2(evslw); | |
4703 | +GEN_SPEOP_ARITH2(evrlw); | |
4704 | +GEN_SPEOP_ARITH2(evmergehi); | |
4705 | +GEN_SPEOP_ARITH2(evmergelo); | |
4706 | +GEN_SPEOP_ARITH2(evmergehilo); | |
4707 | +GEN_SPEOP_ARITH2(evmergelohi); | |
4708 | + | |
4709 | +/* Arithmetic */ | |
4710 | +GEN_SPEOP_ARITH2(evaddw); | |
4711 | +GEN_SPEOP_ARITH2(evsubfw); | |
4712 | +GEN_SPEOP_ARITH1(evabs); | |
4713 | +GEN_SPEOP_ARITH1(evneg); | |
4714 | +GEN_SPEOP_ARITH1(evextsb); | |
4715 | +GEN_SPEOP_ARITH1(evextsh); | |
4716 | +GEN_SPEOP_ARITH1(evrndw); | |
4717 | +GEN_SPEOP_ARITH1(evcntlzw); | |
4718 | +GEN_SPEOP_ARITH1(evcntlsw); | |
4719 | +static inline void gen_brinc (DisasContext *ctx) | |
4720 | +{ | |
4721 | + /* Note: brinc is usable even if SPE is disabled */ | |
4722 | + gen_op_load_gpr64_T0(rA(ctx->opcode)); | |
4723 | + gen_op_load_gpr64_T1(rB(ctx->opcode)); | |
4724 | + gen_op_brinc(); | |
4725 | + gen_op_store_T0_gpr64(rD(ctx->opcode)); | |
4726 | +} | |
4727 | + | |
4728 | +#define GEN_SPEOP_ARITH_IMM2(name) \ | |
4729 | +static inline void gen_##name##i (DisasContext *ctx) \ | |
4730 | +{ \ | |
4731 | + if (unlikely(!ctx->spe_enabled)) { \ | |
4732 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); \ | |
4733 | + return; \ | |
4734 | + } \ | |
4735 | + gen_op_load_gpr64_T0(rB(ctx->opcode)); \ | |
4736 | + gen_op_splatwi_T1_64(rA(ctx->opcode)); \ | |
4737 | + gen_op_##name(); \ | |
4738 | + gen_op_store_T0_gpr64(rD(ctx->opcode)); \ | |
4739 | +} | |
4740 | + | |
4741 | +#define GEN_SPEOP_LOGIC_IMM2(name) \ | |
4742 | +static inline void gen_##name##i (DisasContext *ctx) \ | |
4743 | +{ \ | |
4744 | + if (unlikely(!ctx->spe_enabled)) { \ | |
4745 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); \ | |
4746 | + return; \ | |
4747 | + } \ | |
4748 | + gen_op_load_gpr64_T0(rA(ctx->opcode)); \ | |
4749 | + gen_op_splatwi_T1_64(rB(ctx->opcode)); \ | |
4750 | + gen_op_##name(); \ | |
4751 | + gen_op_store_T0_gpr64(rD(ctx->opcode)); \ | |
4752 | +} | |
4753 | + | |
4754 | +GEN_SPEOP_ARITH_IMM2(evaddw); | |
4755 | +#define gen_evaddiw gen_evaddwi | |
4756 | +GEN_SPEOP_ARITH_IMM2(evsubfw); | |
4757 | +#define gen_evsubifw gen_evsubfwi | |
4758 | +GEN_SPEOP_LOGIC_IMM2(evslw); | |
4759 | +GEN_SPEOP_LOGIC_IMM2(evsrwu); | |
4760 | +#define gen_evsrwis gen_evsrwsi | |
4761 | +GEN_SPEOP_LOGIC_IMM2(evsrws); | |
4762 | +#define gen_evsrwiu gen_evsrwui | |
4763 | +GEN_SPEOP_LOGIC_IMM2(evrlw); | |
4764 | + | |
4765 | +static inline void gen_evsplati (DisasContext *ctx) | |
4766 | +{ | |
4767 | + int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27; | |
4768 | + | |
4769 | + gen_op_splatwi_T0_64(imm); | |
4770 | + gen_op_store_T0_gpr64(rD(ctx->opcode)); | |
4771 | +} | |
4772 | + | |
4773 | +static inline void gen_evsplatfi (DisasContext *ctx) | |
4774 | +{ | |
4775 | + uint32_t imm = rA(ctx->opcode) << 27; | |
4776 | + | |
4777 | + gen_op_splatwi_T0_64(imm); | |
4778 | + gen_op_store_T0_gpr64(rD(ctx->opcode)); | |
4779 | +} | |
4780 | + | |
4781 | +/* Comparison */ | |
4782 | +GEN_SPEOP_COMP(evcmpgtu); | |
4783 | +GEN_SPEOP_COMP(evcmpgts); | |
4784 | +GEN_SPEOP_COMP(evcmpltu); | |
4785 | +GEN_SPEOP_COMP(evcmplts); | |
4786 | +GEN_SPEOP_COMP(evcmpeq); | |
4787 | + | |
4788 | +GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, PPC_SPE); //// | |
4789 | +GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, PPC_SPE); | |
4790 | +GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, PPC_SPE); //// | |
4791 | +GEN_SPE(evsubifw, speundef, 0x03, 0x08, 0x00000000, PPC_SPE); | |
4792 | +GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, PPC_SPE); //// | |
4793 | +GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, PPC_SPE); //// | |
4794 | +GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, PPC_SPE); //// | |
4795 | +GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x00000000, PPC_SPE); // | |
4796 | +GEN_SPE(speundef, evand, 0x08, 0x08, 0x00000000, PPC_SPE); //// | |
4797 | +GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, PPC_SPE); //// | |
4798 | +GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, PPC_SPE); //// | |
4799 | +GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, PPC_SPE); //// | |
4800 | +GEN_SPE(speundef, evorc, 0x0D, 0x08, 0x00000000, PPC_SPE); //// | |
4801 | +GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, PPC_SPE); //// | |
4802 | +GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, PPC_SPE); //// | |
4803 | +GEN_SPE(evsrwiu, evsrwis, 0x11, 0x08, 0x00000000, PPC_SPE); | |
4804 | +GEN_SPE(evslw, speundef, 0x12, 0x08, 0x00000000, PPC_SPE); //// | |
4805 | +GEN_SPE(evslwi, speundef, 0x13, 0x08, 0x00000000, PPC_SPE); | |
4806 | +GEN_SPE(evrlw, evsplati, 0x14, 0x08, 0x00000000, PPC_SPE); // | |
4807 | +GEN_SPE(evrlwi, evsplatfi, 0x15, 0x08, 0x00000000, PPC_SPE); | |
4808 | +GEN_SPE(evmergehi, evmergelo, 0x16, 0x08, 0x00000000, PPC_SPE); //// | |
4809 | +GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, PPC_SPE); //// | |
4810 | +GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, PPC_SPE); //// | |
4811 | +GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, PPC_SPE); //// | |
4812 | +GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, PPC_SPE); //// | |
4813 | + | |
4814 | +static inline void gen_evsel (DisasContext *ctx) | |
4815 | +{ | |
4816 | + if (unlikely(!ctx->spe_enabled)) { | |
4817 | + RET_EXCP(ctx, EXCP_NO_SPE, 0); | |
4818 | + return; | |
4819 | + } | |
4820 | + gen_op_load_crf_T0(ctx->opcode & 0x7); | |
4821 | + gen_op_load_gpr64_T0(rA(ctx->opcode)); | |
4822 | + gen_op_load_gpr64_T1(rB(ctx->opcode)); | |
4823 | + gen_op_evsel(); | |
4824 | + gen_op_store_T0_gpr64(rD(ctx->opcode)); | |
4825 | +} | |
4826 | + | |
4827 | +GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE) | |
4828 | +{ | |
4829 | + gen_evsel(ctx); | |
4830 | +} | |
4831 | +GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE) | |
4832 | +{ | |
4833 | + gen_evsel(ctx); | |
4834 | +} | |
4835 | +GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE) | |
4836 | +{ | |
4837 | + gen_evsel(ctx); | |
4838 | +} | |
4839 | +GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE) | |
4840 | +{ | |
4841 | + gen_evsel(ctx); | |
4842 | +} | |
4843 | + | |
4844 | +/* Load and stores */ | |
4845 | +#if defined(TARGET_PPC64) | |
4846 | +/* In that case, we already have 64 bits load & stores | |
4847 | + * so, spe_ldd is equivalent to ld and spe_std is equivalent to std | |
4848 | + */ | |
4849 | +#if defined(CONFIG_USER_ONLY) | |
4850 | +#define gen_op_spe_ldd_raw gen_op_ld_raw | |
4851 | +#define gen_op_spe_ldd_64_raw gen_op_ld_64_raw | |
4852 | +#define gen_op_spe_ldd_le_raw gen_op_ld_le_raw | |
4853 | +#define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw | |
4854 | +#define gen_op_spe_stdd_raw gen_op_ld_raw | |
4855 | +#define gen_op_spe_stdd_64_raw gen_op_std_64_raw | |
4856 | +#define gen_op_spe_stdd_le_raw gen_op_std_le_raw | |
4857 | +#define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw | |
4858 | +#else /* defined(CONFIG_USER_ONLY) */ | |
4859 | +#define gen_op_spe_ldd_kernel gen_op_ld_kernel | |
4860 | +#define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel | |
4861 | +#define gen_op_spe_ldd_le_kernel gen_op_ld_kernel | |
4862 | +#define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel | |
4863 | +#define gen_op_spe_ldd_user gen_op_ld_user | |
4864 | +#define gen_op_spe_ldd_64_user gen_op_ld_64_user | |
4865 | +#define gen_op_spe_ldd_le_user gen_op_ld_le_user | |
4866 | +#define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user | |
4867 | +#define gen_op_spe_stdd_kernel gen_op_std_kernel | |
4868 | +#define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel | |
4869 | +#define gen_op_spe_stdd_le_kernel gen_op_std_kernel | |
4870 | +#define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel | |
4871 | +#define gen_op_spe_stdd_user gen_op_std_user | |
4872 | +#define gen_op_spe_stdd_64_user gen_op_std_64_user | |
4873 | +#define gen_op_spe_stdd_le_user gen_op_std_le_user | |
4874 | +#define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user | |
4875 | +#endif /* defined(CONFIG_USER_ONLY) */ | |
4876 | +#endif /* defined(TARGET_PPC64) */ | |
4877 | +GEN_SPEOP_LDST(dd, 3); | |
4878 | +GEN_SPEOP_LDST(dw, 3); | |
4879 | +GEN_SPEOP_LDST(dh, 3); | |
4880 | +GEN_SPEOP_LDST(whe, 2); | |
4881 | +GEN_SPEOP_LD(whou, 2); | |
4882 | +GEN_SPEOP_LD(whos, 2); | |
4883 | +GEN_SPEOP_ST(who, 2); | |
4884 | + | |
4885 | +#if defined(TARGET_PPC64) | |
4886 | +/* In that case, spe_stwwo is equivalent to stw */ | |
4887 | +#if defined(CONFIG_USER_ONLY) | |
4888 | +#define gen_op_spe_stwwo_raw gen_op_stw_raw | |
4889 | +#define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw | |
4890 | +#define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw | |
4891 | +#define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw | |
4892 | +#else | |
4893 | +#define gen_op_spe_stwwo_user gen_op_stw_user | |
4894 | +#define gen_op_spe_stwwo_le_user gen_op_stw_le_user | |
4895 | +#define gen_op_spe_stwwo_64_user gen_op_stw_64_user | |
4896 | +#define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user | |
4897 | +#define gen_op_spe_stwwo_kernel gen_op_stw_kernel | |
4898 | +#define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel | |
4899 | +#define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel | |
4900 | +#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel | |
4901 | +#endif | |
4902 | +#endif | |
4903 | +#define _GEN_OP_SPE_STWWE(suffix) \ | |
4904 | +static inline void gen_op_spe_stwwe_##suffix (void) \ | |
4905 | +{ \ | |
4906 | + gen_op_srli32_T1_64(); \ | |
4907 | + gen_op_spe_stwwo_##suffix(); \ | |
4908 | +} | |
4909 | +#define _GEN_OP_SPE_STWWE_LE(suffix) \ | |
4910 | +static inline void gen_op_spe_stwwe_le_##suffix (void) \ | |
4911 | +{ \ | |
4912 | + gen_op_srli32_T1_64(); \ | |
4913 | + gen_op_spe_stwwo_le_##suffix(); \ | |
4914 | +} | |
4915 | +#if defined(TARGET_PPC64) | |
4916 | +#define GEN_OP_SPE_STWWE(suffix) \ | |
4917 | +_GEN_OP_SPE_STWWE(suffix); \ | |
4918 | +_GEN_OP_SPE_STWWE_LE(suffix); \ | |
4919 | +static inline void gen_op_spe_stwwe_64_##suffix (void) \ | |
4920 | +{ \ | |
4921 | + gen_op_srli32_T1_64(); \ | |
4922 | + gen_op_spe_stwwo_64_##suffix(); \ | |
4923 | +} \ | |
4924 | +static inline void gen_op_spe_stwwe_le_64_##suffix (void) \ | |
4925 | +{ \ | |
4926 | + gen_op_srli32_T1_64(); \ | |
4927 | + gen_op_spe_stwwo_le_64_##suffix(); \ | |
4928 | +} | |
4929 | +#else | |
4930 | +#define GEN_OP_SPE_STWWE(suffix) \ | |
4931 | +_GEN_OP_SPE_STWWE(suffix); \ | |
4932 | +_GEN_OP_SPE_STWWE_LE(suffix) | |
4933 | +#endif | |
4934 | +#if defined(CONFIG_USER_ONLY) | |
4935 | +GEN_OP_SPE_STWWE(raw); | |
4936 | +#else /* defined(CONFIG_USER_ONLY) */ | |
4937 | +GEN_OP_SPE_STWWE(kernel); | |
4938 | +GEN_OP_SPE_STWWE(user); | |
4939 | +#endif /* defined(CONFIG_USER_ONLY) */ | |
4940 | +GEN_SPEOP_ST(wwe, 2); | |
4941 | +GEN_SPEOP_ST(wwo, 2); | |
4942 | + | |
4943 | +#define GEN_SPE_LDSPLAT(name, op, suffix) \ | |
4944 | +static inline void gen_op_spe_l##name##_##suffix (void) \ | |
4945 | +{ \ | |
4946 | + gen_op_##op##_##suffix(); \ | |
4947 | + gen_op_splatw_T1_64(); \ | |
4948 | +} | |
4949 | + | |
4950 | +#define GEN_OP_SPE_LHE(suffix) \ | |
4951 | +static inline void gen_op_spe_lhe_##suffix (void) \ | |
4952 | +{ \ | |
4953 | + gen_op_spe_lh_##suffix(); \ | |
4954 | + gen_op_sli16_T1_64(); \ | |
4955 | +} | |
4956 | + | |
4957 | +#define GEN_OP_SPE_LHX(suffix) \ | |
4958 | +static inline void gen_op_spe_lhx_##suffix (void) \ | |
4959 | +{ \ | |
4960 | + gen_op_spe_lh_##suffix(); \ | |
4961 | + gen_op_extsh_T1_64(); \ | |
4962 | +} | |
4963 | + | |
4964 | +#if defined(CONFIG_USER_ONLY) | |
4965 | +GEN_OP_SPE_LHE(raw); | |
4966 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw); | |
4967 | +GEN_OP_SPE_LHE(le_raw); | |
4968 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw); | |
4969 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw); | |
4970 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw); | |
4971 | +GEN_OP_SPE_LHX(raw); | |
4972 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw); | |
4973 | +GEN_OP_SPE_LHX(le_raw); | |
4974 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw); | |
4975 | +#if defined(TARGET_PPC64) | |
4976 | +GEN_OP_SPE_LHE(64_raw); | |
4977 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw); | |
4978 | +GEN_OP_SPE_LHE(le_64_raw); | |
4979 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw); | |
4980 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw); | |
4981 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw); | |
4982 | +GEN_OP_SPE_LHX(64_raw); | |
4983 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw); | |
4984 | +GEN_OP_SPE_LHX(le_64_raw); | |
4985 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw); | |
4986 | +#endif | |
4987 | +#else | |
4988 | +GEN_OP_SPE_LHE(kernel); | |
4989 | +GEN_OP_SPE_LHE(user); | |
4990 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel); | |
4991 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user); | |
4992 | +GEN_OP_SPE_LHE(le_kernel); | |
4993 | +GEN_OP_SPE_LHE(le_user); | |
4994 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel); | |
4995 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user); | |
4996 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel); | |
4997 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, user); | |
4998 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel); | |
4999 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user); | |
5000 | +GEN_OP_SPE_LHX(kernel); | |
5001 | +GEN_OP_SPE_LHX(user); | |
5002 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel); | |
5003 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user); | |
5004 | +GEN_OP_SPE_LHX(le_kernel); | |
5005 | +GEN_OP_SPE_LHX(le_user); | |
5006 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel); | |
5007 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user); | |
5008 | +#if defined(TARGET_PPC64) | |
5009 | +GEN_OP_SPE_LHE(64_kernel); | |
5010 | +GEN_OP_SPE_LHE(64_user); | |
5011 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel); | |
5012 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user); | |
5013 | +GEN_OP_SPE_LHE(le_64_kernel); | |
5014 | +GEN_OP_SPE_LHE(le_64_user); | |
5015 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel); | |
5016 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user); | |
5017 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel); | |
5018 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user); | |
5019 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel); | |
5020 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user); | |
5021 | +GEN_OP_SPE_LHX(64_kernel); | |
5022 | +GEN_OP_SPE_LHX(64_user); | |
5023 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel); | |
5024 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user); | |
5025 | +GEN_OP_SPE_LHX(le_64_kernel); | |
5026 | +GEN_OP_SPE_LHX(le_64_user); | |
5027 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel); | |
5028 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user); | |
5029 | +#endif | |
5030 | +#endif | |
5031 | +GEN_SPEOP_LD(hhesplat, 1); | |
5032 | +GEN_SPEOP_LD(hhousplat, 1); | |
5033 | +GEN_SPEOP_LD(hhossplat, 1); | |
5034 | +GEN_SPEOP_LD(wwsplat, 2); | |
5035 | +GEN_SPEOP_LD(whsplat, 2); | |
5036 | + | |
5037 | +GEN_SPE(evlddx, evldd, 0x00, 0x0C, 0x00000000, PPC_SPE); // | |
5038 | +GEN_SPE(evldwx, evldw, 0x01, 0x0C, 0x00000000, PPC_SPE); // | |
5039 | +GEN_SPE(evldhx, evldh, 0x02, 0x0C, 0x00000000, PPC_SPE); // | |
5040 | +GEN_SPE(evlhhesplatx, evlhhesplat, 0x04, 0x0C, 0x00000000, PPC_SPE); // | |
5041 | +GEN_SPE(evlhhousplatx, evlhhousplat, 0x06, 0x0C, 0x00000000, PPC_SPE); // | |
5042 | +GEN_SPE(evlhhossplatx, evlhhossplat, 0x07, 0x0C, 0x00000000, PPC_SPE); // | |
5043 | +GEN_SPE(evlwhex, evlwhe, 0x08, 0x0C, 0x00000000, PPC_SPE); // | |
5044 | +GEN_SPE(evlwhoux, evlwhou, 0x0A, 0x0C, 0x00000000, PPC_SPE); // | |
5045 | +GEN_SPE(evlwhosx, evlwhos, 0x0B, 0x0C, 0x00000000, PPC_SPE); // | |
5046 | +GEN_SPE(evlwwsplatx, evlwwsplat, 0x0C, 0x0C, 0x00000000, PPC_SPE); // | |
5047 | +GEN_SPE(evlwhsplatx, evlwhsplat, 0x0E, 0x0C, 0x00000000, PPC_SPE); // | |
5048 | +GEN_SPE(evstddx, evstdd, 0x10, 0x0C, 0x00000000, PPC_SPE); // | |
5049 | +GEN_SPE(evstdwx, evstdw, 0x11, 0x0C, 0x00000000, PPC_SPE); // | |
5050 | +GEN_SPE(evstdhx, evstdh, 0x12, 0x0C, 0x00000000, PPC_SPE); // | |
5051 | +GEN_SPE(evstwhex, evstwhe, 0x18, 0x0C, 0x00000000, PPC_SPE); // | |
5052 | +GEN_SPE(evstwhox, evstwho, 0x1A, 0x0C, 0x00000000, PPC_SPE); // | |
5053 | +GEN_SPE(evstwwex, evstwwe, 0x1C, 0x0C, 0x00000000, PPC_SPE); // | |
5054 | +GEN_SPE(evstwwox, evstwwo, 0x1E, 0x0C, 0x00000000, PPC_SPE); // | |
5055 | + | |
5056 | +/* Multiply and add - TODO */ | |
5057 | +#if 0 | |
5058 | +GEN_SPE(speundef, evmhessf, 0x01, 0x10, 0x00000000, PPC_SPE); | |
5059 | +GEN_SPE(speundef, evmhossf, 0x03, 0x10, 0x00000000, PPC_SPE); | |
5060 | +GEN_SPE(evmheumi, evmhesmi, 0x04, 0x10, 0x00000000, PPC_SPE); | |
5061 | +GEN_SPE(speundef, evmhesmf, 0x05, 0x10, 0x00000000, PPC_SPE); | |
5062 | +GEN_SPE(evmhoumi, evmhosmi, 0x06, 0x10, 0x00000000, PPC_SPE); | |
5063 | +GEN_SPE(speundef, evmhosmf, 0x07, 0x10, 0x00000000, PPC_SPE); | |
5064 | +GEN_SPE(speundef, evmhessfa, 0x11, 0x10, 0x00000000, PPC_SPE); | |
5065 | +GEN_SPE(speundef, evmhossfa, 0x13, 0x10, 0x00000000, PPC_SPE); | |
5066 | +GEN_SPE(evmheumia, evmhesmia, 0x14, 0x10, 0x00000000, PPC_SPE); | |
5067 | +GEN_SPE(speundef, evmhesmfa, 0x15, 0x10, 0x00000000, PPC_SPE); | |
5068 | +GEN_SPE(evmhoumia, evmhosmia, 0x16, 0x10, 0x00000000, PPC_SPE); | |
5069 | +GEN_SPE(speundef, evmhosmfa, 0x17, 0x10, 0x00000000, PPC_SPE); | |
5070 | + | |
5071 | +GEN_SPE(speundef, evmwhssf, 0x03, 0x11, 0x00000000, PPC_SPE); | |
5072 | +GEN_SPE(evmwlumi, speundef, 0x04, 0x11, 0x00000000, PPC_SPE); | |
5073 | +GEN_SPE(evmwhumi, evmwhsmi, 0x06, 0x11, 0x00000000, PPC_SPE); | |
5074 | +GEN_SPE(speundef, evmwhsmf, 0x07, 0x11, 0x00000000, PPC_SPE); | |
5075 | +GEN_SPE(speundef, evmwssf, 0x09, 0x11, 0x00000000, PPC_SPE); | |
5076 | +GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, PPC_SPE); | |
5077 | +GEN_SPE(speundef, evmwsmf, 0x0D, 0x11, 0x00000000, PPC_SPE); | |
5078 | +GEN_SPE(speundef, evmwhssfa, 0x13, 0x11, 0x00000000, PPC_SPE); | |
5079 | +GEN_SPE(evmwlumia, speundef, 0x14, 0x11, 0x00000000, PPC_SPE); | |
5080 | +GEN_SPE(evmwhumia, evmwhsmia, 0x16, 0x11, 0x00000000, PPC_SPE); | |
5081 | +GEN_SPE(speundef, evmwhsmfa, 0x17, 0x11, 0x00000000, PPC_SPE); | |
5082 | +GEN_SPE(speundef, evmwssfa, 0x19, 0x11, 0x00000000, PPC_SPE); | |
5083 | +GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, PPC_SPE); | |
5084 | +GEN_SPE(speundef, evmwsmfa, 0x1D, 0x11, 0x00000000, PPC_SPE); | |
5085 | + | |
5086 | +GEN_SPE(evadduiaaw, evaddsiaaw, 0x00, 0x13, 0x0000F800, PPC_SPE); | |
5087 | +GEN_SPE(evsubfusiaaw, evsubfssiaaw, 0x01, 0x13, 0x0000F800, PPC_SPE); | |
5088 | +GEN_SPE(evaddumiaaw, evaddsmiaaw, 0x04, 0x13, 0x0000F800, PPC_SPE); | |
5089 | +GEN_SPE(evsubfumiaaw, evsubfsmiaaw, 0x05, 0x13, 0x0000F800, PPC_SPE); | |
5090 | +GEN_SPE(evdivws, evdivwu, 0x06, 0x13, 0x00000000, PPC_SPE); | |
5091 | +GEN_SPE(evmra, speundef, 0x07, 0x13, 0x0000F800, PPC_SPE); | |
5092 | + | |
5093 | +GEN_SPE(evmheusiaaw, evmhessiaaw, 0x00, 0x14, 0x00000000, PPC_SPE); | |
5094 | +GEN_SPE(speundef, evmhessfaaw, 0x01, 0x14, 0x00000000, PPC_SPE); | |
5095 | +GEN_SPE(evmhousiaaw, evmhossiaaw, 0x02, 0x14, 0x00000000, PPC_SPE); | |
5096 | +GEN_SPE(speundef, evmhossfaaw, 0x03, 0x14, 0x00000000, PPC_SPE); | |
5097 | +GEN_SPE(evmheumiaaw, evmhesmiaaw, 0x04, 0x14, 0x00000000, PPC_SPE); | |
5098 | +GEN_SPE(speundef, evmhesmfaaw, 0x05, 0x14, 0x00000000, PPC_SPE); | |
5099 | +GEN_SPE(evmhoumiaaw, evmhosmiaaw, 0x06, 0x14, 0x00000000, PPC_SPE); | |
5100 | +GEN_SPE(speundef, evmhosmfaaw, 0x07, 0x14, 0x00000000, PPC_SPE); | |
5101 | +GEN_SPE(evmhegumiaa, evmhegsmiaa, 0x14, 0x14, 0x00000000, PPC_SPE); | |
5102 | +GEN_SPE(speundef, evmhegsmfaa, 0x15, 0x14, 0x00000000, PPC_SPE); | |
5103 | +GEN_SPE(evmhogumiaa, evmhogsmiaa, 0x16, 0x14, 0x00000000, PPC_SPE); | |
5104 | +GEN_SPE(speundef, evmhogsmfaa, 0x17, 0x14, 0x00000000, PPC_SPE); | |
5105 | + | |
5106 | +GEN_SPE(evmwlusiaaw, evmwlssiaaw, 0x00, 0x15, 0x00000000, PPC_SPE); | |
5107 | +GEN_SPE(evmwlumiaaw, evmwlsmiaaw, 0x04, 0x15, 0x00000000, PPC_SPE); | |
5108 | +GEN_SPE(speundef, evmwssfaa, 0x09, 0x15, 0x00000000, PPC_SPE); | |
5109 | +GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, PPC_SPE); | |
5110 | +GEN_SPE(speundef, evmwsmfaa, 0x0D, 0x15, 0x00000000, PPC_SPE); | |
5111 | + | |
5112 | +GEN_SPE(evmheusianw, evmhessianw, 0x00, 0x16, 0x00000000, PPC_SPE); | |
5113 | +GEN_SPE(speundef, evmhessfanw, 0x01, 0x16, 0x00000000, PPC_SPE); | |
5114 | +GEN_SPE(evmhousianw, evmhossianw, 0x02, 0x16, 0x00000000, PPC_SPE); | |
5115 | +GEN_SPE(speundef, evmhossfanw, 0x03, 0x16, 0x00000000, PPC_SPE); | |
5116 | +GEN_SPE(evmheumianw, evmhesmianw, 0x04, 0x16, 0x00000000, PPC_SPE); | |
5117 | +GEN_SPE(speundef, evmhesmfanw, 0x05, 0x16, 0x00000000, PPC_SPE); | |
5118 | +GEN_SPE(evmhoumianw, evmhosmianw, 0x06, 0x16, 0x00000000, PPC_SPE); | |
5119 | +GEN_SPE(speundef, evmhosmfanw, 0x07, 0x16, 0x00000000, PPC_SPE); | |
5120 | +GEN_SPE(evmhegumian, evmhegsmian, 0x14, 0x16, 0x00000000, PPC_SPE); | |
5121 | +GEN_SPE(speundef, evmhegsmfan, 0x15, 0x16, 0x00000000, PPC_SPE); | |
5122 | +GEN_SPE(evmhigumian, evmhigsmian, 0x16, 0x16, 0x00000000, PPC_SPE); | |
5123 | +GEN_SPE(speundef, evmhogsmfan, 0x17, 0x16, 0x00000000, PPC_SPE); | |
5124 | + | |
5125 | +GEN_SPE(evmwlusianw, evmwlssianw, 0x00, 0x17, 0x00000000, PPC_SPE); | |
5126 | +GEN_SPE(evmwlumianw, evmwlsmianw, 0x04, 0x17, 0x00000000, PPC_SPE); | |
5127 | +GEN_SPE(speundef, evmwssfan, 0x09, 0x17, 0x00000000, PPC_SPE); | |
5128 | +GEN_SPE(evmwumian, evmwsmian, 0x0C, 0x17, 0x00000000, PPC_SPE); | |
5129 | +GEN_SPE(speundef, evmwsmfan, 0x0D, 0x17, 0x00000000, PPC_SPE); | |
5130 | +#endif | |
5131 | + | |
5132 | +/*** SPE floating-point extension ***/ | |
5133 | +#define GEN_SPEFPUOP_CONV(name) \ | |
5134 | +static inline void gen_##name (DisasContext *ctx) \ | |
5135 | +{ \ | |
5136 | + gen_op_load_gpr64_T0(rB(ctx->opcode)); \ | |
5137 | + gen_op_##name(); \ | |
5138 | + gen_op_store_T0_gpr64(rD(ctx->opcode)); \ | |
5139 | +} | |
5140 | + | |
5141 | +/* Single precision floating-point vectors operations */ | |
5142 | +/* Arithmetic */ | |
5143 | +GEN_SPEOP_ARITH2(evfsadd); | |
5144 | +GEN_SPEOP_ARITH2(evfssub); | |
5145 | +GEN_SPEOP_ARITH2(evfsmul); | |
5146 | +GEN_SPEOP_ARITH2(evfsdiv); | |
5147 | +GEN_SPEOP_ARITH1(evfsabs); | |
5148 | +GEN_SPEOP_ARITH1(evfsnabs); | |
5149 | +GEN_SPEOP_ARITH1(evfsneg); | |
5150 | +/* Conversion */ | |
5151 | +GEN_SPEFPUOP_CONV(evfscfui); | |
5152 | +GEN_SPEFPUOP_CONV(evfscfsi); | |
5153 | +GEN_SPEFPUOP_CONV(evfscfuf); | |
5154 | +GEN_SPEFPUOP_CONV(evfscfsf); | |
5155 | +GEN_SPEFPUOP_CONV(evfsctui); | |
5156 | +GEN_SPEFPUOP_CONV(evfsctsi); | |
5157 | +GEN_SPEFPUOP_CONV(evfsctuf); | |
5158 | +GEN_SPEFPUOP_CONV(evfsctsf); | |
5159 | +GEN_SPEFPUOP_CONV(evfsctuiz); | |
5160 | +GEN_SPEFPUOP_CONV(evfsctsiz); | |
5161 | +/* Comparison */ | |
5162 | +GEN_SPEOP_COMP(evfscmpgt); | |
5163 | +GEN_SPEOP_COMP(evfscmplt); | |
5164 | +GEN_SPEOP_COMP(evfscmpeq); | |
5165 | +GEN_SPEOP_COMP(evfststgt); | |
5166 | +GEN_SPEOP_COMP(evfststlt); | |
5167 | +GEN_SPEOP_COMP(evfststeq); | |
5168 | + | |
5169 | +/* Opcodes definitions */ | |
5170 | +GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, PPC_SPEFPU); // | |
5171 | +GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, PPC_SPEFPU); // | |
5172 | +GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, PPC_SPEFPU); // | |
5173 | +GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, PPC_SPEFPU); // | |
5174 | +GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, PPC_SPEFPU); // | |
5175 | +GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, PPC_SPEFPU); // | |
5176 | +GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, PPC_SPEFPU); // | |
5177 | +GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, PPC_SPEFPU); // | |
5178 | +GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, PPC_SPEFPU); // | |
5179 | +GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, PPC_SPEFPU); // | |
5180 | +GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, PPC_SPEFPU); // | |
5181 | +GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, PPC_SPEFPU); // | |
5182 | +GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, PPC_SPEFPU); // | |
5183 | +GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, PPC_SPEFPU); // | |
5184 | + | |
5185 | +/* Single precision floating-point operations */ | |
5186 | +/* Arithmetic */ | |
5187 | +GEN_SPEOP_ARITH2(efsadd); | |
5188 | +GEN_SPEOP_ARITH2(efssub); | |
5189 | +GEN_SPEOP_ARITH2(efsmul); | |
5190 | +GEN_SPEOP_ARITH2(efsdiv); | |
5191 | +GEN_SPEOP_ARITH1(efsabs); | |
5192 | +GEN_SPEOP_ARITH1(efsnabs); | |
5193 | +GEN_SPEOP_ARITH1(efsneg); | |
5194 | +/* Conversion */ | |
5195 | +GEN_SPEFPUOP_CONV(efscfui); | |
5196 | +GEN_SPEFPUOP_CONV(efscfsi); | |
5197 | +GEN_SPEFPUOP_CONV(efscfuf); | |
5198 | +GEN_SPEFPUOP_CONV(efscfsf); | |
5199 | +GEN_SPEFPUOP_CONV(efsctui); | |
5200 | +GEN_SPEFPUOP_CONV(efsctsi); | |
5201 | +GEN_SPEFPUOP_CONV(efsctuf); | |
5202 | +GEN_SPEFPUOP_CONV(efsctsf); | |
5203 | +GEN_SPEFPUOP_CONV(efsctuiz); | |
5204 | +GEN_SPEFPUOP_CONV(efsctsiz); | |
5205 | +GEN_SPEFPUOP_CONV(efscfd); | |
5206 | +/* Comparison */ | |
5207 | +GEN_SPEOP_COMP(efscmpgt); | |
5208 | +GEN_SPEOP_COMP(efscmplt); | |
5209 | +GEN_SPEOP_COMP(efscmpeq); | |
5210 | +GEN_SPEOP_COMP(efststgt); | |
5211 | +GEN_SPEOP_COMP(efststlt); | |
5212 | +GEN_SPEOP_COMP(efststeq); | |
5213 | + | |
5214 | +/* Opcodes definitions */ | |
5215 | +GEN_SPE(efsadd, efssub, 0x00, 0x0A, 0x00000000, PPC_SPEFPU); // | |
5216 | +GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, PPC_SPEFPU); // | |
5217 | +GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, PPC_SPEFPU); // | |
5218 | +GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, PPC_SPEFPU); // | |
5219 | +GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, PPC_SPEFPU); // | |
5220 | +GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, PPC_SPEFPU); // | |
5221 | +GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5222 | +GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5223 | +GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5224 | +GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5225 | +GEN_SPE(efsctuiz, efsctsiz, 0x0C, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5226 | +GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, PPC_SPEFPU); // | |
5227 | +GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, PPC_SPEFPU); // | |
5228 | + | |
5229 | +/* Double precision floating-point operations */ | |
5230 | +/* Arithmetic */ | |
5231 | +GEN_SPEOP_ARITH2(efdadd); | |
5232 | +GEN_SPEOP_ARITH2(efdsub); | |
5233 | +GEN_SPEOP_ARITH2(efdmul); | |
5234 | +GEN_SPEOP_ARITH2(efddiv); | |
5235 | +GEN_SPEOP_ARITH1(efdabs); | |
5236 | +GEN_SPEOP_ARITH1(efdnabs); | |
5237 | +GEN_SPEOP_ARITH1(efdneg); | |
5238 | +/* Conversion */ | |
5239 | + | |
5240 | +GEN_SPEFPUOP_CONV(efdcfui); | |
5241 | +GEN_SPEFPUOP_CONV(efdcfsi); | |
5242 | +GEN_SPEFPUOP_CONV(efdcfuf); | |
5243 | +GEN_SPEFPUOP_CONV(efdcfsf); | |
5244 | +GEN_SPEFPUOP_CONV(efdctui); | |
5245 | +GEN_SPEFPUOP_CONV(efdctsi); | |
5246 | +GEN_SPEFPUOP_CONV(efdctuf); | |
5247 | +GEN_SPEFPUOP_CONV(efdctsf); | |
5248 | +GEN_SPEFPUOP_CONV(efdctuiz); | |
5249 | +GEN_SPEFPUOP_CONV(efdctsiz); | |
5250 | +GEN_SPEFPUOP_CONV(efdcfs); | |
5251 | +GEN_SPEFPUOP_CONV(efdcfuid); | |
5252 | +GEN_SPEFPUOP_CONV(efdcfsid); | |
5253 | +GEN_SPEFPUOP_CONV(efdctuidz); | |
5254 | +GEN_SPEFPUOP_CONV(efdctsidz); | |
5255 | +/* Comparison */ | |
5256 | +GEN_SPEOP_COMP(efdcmpgt); | |
5257 | +GEN_SPEOP_COMP(efdcmplt); | |
5258 | +GEN_SPEOP_COMP(efdcmpeq); | |
5259 | +GEN_SPEOP_COMP(efdtstgt); | |
5260 | +GEN_SPEOP_COMP(efdtstlt); | |
5261 | +GEN_SPEOP_COMP(efdtsteq); | |
5262 | + | |
5263 | +/* Opcodes definitions */ | |
5264 | +GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, PPC_SPEFPU); // | |
5265 | +GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5266 | +GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, PPC_SPEFPU); // | |
5267 | +GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, PPC_SPEFPU); // | |
5268 | +GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, PPC_SPEFPU); // | |
5269 | +GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5270 | +GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, PPC_SPEFPU); // | |
5271 | +GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, PPC_SPEFPU); // | |
5272 | +GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5273 | +GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5274 | +GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5275 | +GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5276 | +GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5277 | +GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, PPC_SPEFPU); // | |
5278 | +GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, PPC_SPEFPU); // | |
5279 | +GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, PPC_SPEFPU); // | |
5280 | +#endif | |
5281 | + | |
4471 | 5282 | /* End opcode list */ |
4472 | 5283 | GEN_OPCODE_MARK(end); |
4473 | 5284 | |
... | ... | @@ -4604,9 +5415,9 @@ void cpu_dump_statistics (CPUState *env, FILE*f, |
4604 | 5415 | } |
4605 | 5416 | |
4606 | 5417 | /*****************************************************************************/ |
4607 | -static inline int | |
4608 | -gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | |
4609 | - int search_pc) | |
5418 | +static inline int gen_intermediate_code_internal (CPUState *env, | |
5419 | + TranslationBlock *tb, | |
5420 | + int search_pc) | |
4610 | 5421 | { |
4611 | 5422 | DisasContext ctx, *ctxp = &ctx; |
4612 | 5423 | opc_handler_t **table, *handler; |
... | ... | @@ -4639,6 +5450,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
4639 | 5450 | ctx.sf_mode = msr_sf; |
4640 | 5451 | #endif |
4641 | 5452 | ctx.fpu_enabled = msr_fp; |
5453 | +#if defined(TARGET_PPCSPE) | |
5454 | + ctx.spe_enabled = msr_spe; | |
5455 | +#endif | |
4642 | 5456 | ctx.singlestep_enabled = env->singlestep_enabled; |
4643 | 5457 | #if defined (DO_SINGLE_STEP) && 0 |
4644 | 5458 | /* Single step trace mode */ | ... | ... |
target-ppc/translate_init.c
... | ... | @@ -30,7 +30,7 @@ struct ppc_def_t { |
30 | 30 | const unsigned char *name; |
31 | 31 | uint32_t pvr; |
32 | 32 | uint32_t pvr_mask; |
33 | - uint32_t insns_flags; | |
33 | + uint64_t insns_flags; | |
34 | 34 | uint32_t flags; |
35 | 35 | uint64_t msr_mask; |
36 | 36 | }; |
... | ... | @@ -2424,7 +2424,8 @@ static int create_ppc_opcodes (CPUPPCState *env, ppc_def_t *def) |
2424 | 2424 | |
2425 | 2425 | fill_new_table(env->opcodes, 0x40); |
2426 | 2426 | #if defined(PPC_DUMP_CPU) |
2427 | - printf("* PowerPC instructions for PVR %08x: %s flags %08x %08x\n", | |
2427 | + printf("* PowerPC instructions for PVR %08x: %s flags %016 " PRIx64 | |
2428 | + " %08x\n", | |
2428 | 2429 | def->pvr, def->name, def->insns_flags, def->flags); |
2429 | 2430 | #endif |
2430 | 2431 | if (&opc_start < &opc_end) { | ... | ... |