Revision 0487d6a8
b/target-ppc/cpu.h | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 */ |
b/target-ppc/exec.h | ||
---|---|---|
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) |
b/target-ppc/op.c | ||
---|---|---|
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 | 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) */ |
b/target-ppc/op_helper.c | ||
---|---|---|
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 | 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 | 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 |
|
Also available in: Unified diff