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

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff