Revision 76a66253 target-ppc/translate.c

b/target-ppc/translate.c
1 1
/*
2 2
 *  PowerPC emulation for qemu: main translation routines.
3 3
 * 
4
 *  Copyright (c) 2003-2005 Jocelyn Mayer
4
 *  Copyright (c) 2003-2007 Jocelyn Mayer
5 5
 *
6 6
 * This library is free software; you can redistribute it and/or
7 7
 * modify it under the terms of the GNU Lesser General Public
......
29 29

  
30 30
//#define DO_SINGLE_STEP
31 31
//#define PPC_DEBUG_DISAS
32
//#define DO_PPC_STATISTICS
32 33

  
33 34
#ifdef USE_DIRECT_JUMP
34 35
#define TBPARAM(x)
......
96 97
GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
97 98
GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
98 99
GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
99
static GenOpFunc1 *gen_op_store_T0_fpscri_fpscr_table[8] = {
100
    &gen_op_store_T0_fpscri_fpscr0,
101
    &gen_op_store_T0_fpscri_fpscr1,
102
    &gen_op_store_T0_fpscri_fpscr2,
103
    &gen_op_store_T0_fpscri_fpscr3,
104
    &gen_op_store_T0_fpscri_fpscr4,
105
    &gen_op_store_T0_fpscri_fpscr5,
106
    &gen_op_store_T0_fpscri_fpscr6,
107
    &gen_op_store_T0_fpscri_fpscr7,
108
};
109 100
static inline void gen_op_store_T0_fpscri(int n, uint8_t param)
110 101
{
111
    (*gen_op_store_T0_fpscri_fpscr_table[n])(param);
102
    gen_op_set_T0(param);
103
    gen_op_store_T0_fpscr(n);
112 104
}
113 105

  
114
/* Segment register moves */
115
GEN16(gen_op_load_sr, gen_op_load_sr);
116
GEN16(gen_op_store_sr, gen_op_store_sr);
117

  
118 106
/* General purpose registers moves */
119 107
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
120 108
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
......
122 110

  
123 111
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
124 112
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
113
#if 0 // unused
125 114
GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
115
#endif
126 116

  
127 117
/* floating point registers moves */
128 118
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
......
130 120
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
131 121
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
132 122
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
123
#if 0 // unused
133 124
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
134

  
135
static uint8_t  spr_access[1024 / 2];
125
#endif
136 126

  
137 127
/* internal defines */
138 128
typedef struct DisasContext {
......
158 148
    uint32_t type;
159 149
    /* handler */
160 150
    void (*handler)(DisasContext *ctx);
151
#if defined(DO_PPC_STATISTICS)
152
    const unsigned char *oname;
153
    uint64_t count;
154
#endif
161 155
};
162 156

  
157
static inline void gen_set_Rc0 (DisasContext *ctx)
158
{
159
    gen_op_cmpi(0);
160
    gen_op_set_Rc0();
161
}
162

  
163 163
#define RET_EXCP(ctx, excp, error)                                            \
164 164
do {                                                                          \
165 165
    if ((ctx)->exception == EXCP_NONE) {                                      \
......
209 209

  
210 210
/***                           Instruction decoding                        ***/
211 211
#define EXTRACT_HELPER(name, shift, nb)                                       \
212
static inline uint32_t name (uint32_t opcode)                                 \
212
static inline target_ulong name (uint32_t opcode)                             \
213 213
{                                                                             \
214 214
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
215 215
}
216 216

  
217 217
#define EXTRACT_SHELPER(name, shift, nb)                                      \
218
static inline int32_t name (uint32_t opcode)                                  \
218
static inline target_long name (uint32_t opcode)                              \
219 219
{                                                                             \
220 220
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
221 221
}
......
278 278
/* Displacement */
279 279
EXTRACT_SHELPER(d, 0, 16);
280 280
/* Immediate address */
281
static inline uint32_t LI (uint32_t opcode)
281
static inline target_ulong LI (uint32_t opcode)
282 282
{
283 283
    return (opcode >> 0) & 0x03FFFFFC;
284 284
}
......
296 296
EXTRACT_HELPER(LK, 0, 1);
297 297

  
298 298
/* Create a mask between <start> and <end> bits */
299
static inline uint32_t MASK (uint32_t start, uint32_t end)
299
static inline target_ulong MASK (uint32_t start, uint32_t end)
300 300
{
301
    uint32_t ret;
301
    target_ulong ret;
302 302

  
303
    ret = (((uint32_t)(-1)) >> (start)) ^ (((uint32_t)(-1) >> (end)) >> 1);
304
    if (start > end)
305
        return ~ret;
303
#if defined(TARGET_PPC64)
304
    if (likely(start == 0)) {
305
        ret = (uint64_t)(-1ULL) << (63 - end);
306
    } else if (likely(end == 63)) {
307
        ret = (uint64_t)(-1ULL) >> start;
308
    }
309
#else
310
    if (likely(start == 0)) {
311
        ret = (uint32_t)(-1ULL) << (31  - end);
312
    } else if (likely(end == 31)) {
313
        ret = (uint32_t)(-1ULL) >> start;
314
    }
315
#endif
316
    else {
317
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
318
            (((target_ulong)(-1ULL) >> (end)) >> 1);
319
        if (unlikely(start > end))
320
            return ~ret;
321
    }
306 322

  
307 323
    return ret;
308 324
}
......
320 336
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
321 337
#endif
322 338

  
339
#if defined(DO_PPC_STATISTICS)
323 340
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
324 341
OPCODES_SECTION opcode_t opc_##name = {                                       \
325 342
    .opc1 = op1,                                                              \
......
330 347
        .inval   = invl,                                                      \
331 348
        .type = _typ,                                                         \
332 349
        .handler = &gen_##name,                                               \
350
        .oname = stringify(name),                                             \
333 351
    },                                                                        \
334 352
    .oname = stringify(name),                                                 \
335 353
}
354
#else
355
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
356
OPCODES_SECTION opcode_t opc_##name = {                                       \
357
    .opc1 = op1,                                                              \
358
    .opc2 = op2,                                                              \
359
    .opc3 = op3,                                                              \
360
    .pad  = { 0, },                                                           \
361
    .handler = {                                                              \
362
        .inval   = invl,                                                      \
363
        .type = _typ,                                                         \
364
        .handler = &gen_##name,                                               \
365
    },                                                                        \
366
    .oname = stringify(name),                                                 \
367
}
368
#endif
336 369

  
337 370
#define GEN_OPCODE_MARK(name)                                                 \
338 371
OPCODES_SECTION opcode_t opc_##name = {                                       \
......
370 403
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
371 404
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
372 405
    gen_op_##name();                                                          \
373
    if (Rc(ctx->opcode) != 0)                                                 \
374
        gen_op_set_Rc0();                                                     \
375 406
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
407
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
408
        gen_set_Rc0(ctx);                                                     \
376 409
}
377 410

  
378 411
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval)                     \
......
381 414
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
382 415
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
383 416
    gen_op_##name();                                                          \
384
    if (Rc(ctx->opcode) != 0)                                                 \
385
        gen_op_set_Rc0();                                                     \
386 417
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
418
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
419
        gen_set_Rc0(ctx);                                                     \
387 420
}
388 421

  
389 422
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3)                              \
......
391 424
{                                                                             \
392 425
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
393 426
    gen_op_##name();                                                          \
394
    if (Rc(ctx->opcode) != 0)                                                 \
395
        gen_op_set_Rc0();                                                     \
396 427
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
428
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
429
        gen_set_Rc0(ctx);                                                     \
397 430
}
398 431
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3)                            \
399 432
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER)                  \
400 433
{                                                                             \
401 434
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
402 435
    gen_op_##name();                                                          \
403
    if (Rc(ctx->opcode) != 0)                                                 \
404
        gen_op_set_Rc0();                                                     \
405 436
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
437
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
438
        gen_set_Rc0(ctx);                                                     \
406 439
}
407 440

  
408 441
/* Two operands arithmetic functions */
......
454 487
/* addi */
455 488
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
456 489
{
457
    int32_t simm = SIMM(ctx->opcode);
490
    target_long simm = SIMM(ctx->opcode);
458 491

  
459 492
    if (rA(ctx->opcode) == 0) {
493
        /* li case */
460 494
        gen_op_set_T0(simm);
461 495
    } else {
462 496
        gen_op_load_gpr_T0(rA(ctx->opcode));
463
        gen_op_addi(simm);
497
        if (likely(simm != 0))
498
            gen_op_addi(simm);
464 499
    }
465 500
    gen_op_store_T0_gpr(rD(ctx->opcode));
466 501
}
467 502
/* addic */
468 503
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
469 504
{
505
    target_long simm = SIMM(ctx->opcode);
506

  
470 507
    gen_op_load_gpr_T0(rA(ctx->opcode));
471
    gen_op_addic(SIMM(ctx->opcode));
508
    if (likely(simm != 0))
509
        gen_op_addic(SIMM(ctx->opcode));
472 510
    gen_op_store_T0_gpr(rD(ctx->opcode));
473 511
}
474 512
/* addic. */
475 513
GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
476 514
{
515
    target_long simm = SIMM(ctx->opcode);
516

  
477 517
    gen_op_load_gpr_T0(rA(ctx->opcode));
478
    gen_op_addic(SIMM(ctx->opcode));
479
    gen_op_set_Rc0();
518
    if (likely(simm != 0))
519
        gen_op_addic(SIMM(ctx->opcode));
480 520
    gen_op_store_T0_gpr(rD(ctx->opcode));
521
    gen_set_Rc0(ctx);
481 522
}
482 523
/* addis */
483 524
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
484 525
{
485
    int32_t simm = SIMM(ctx->opcode);
526
    target_long simm = SIMM(ctx->opcode);
486 527

  
487 528
    if (rA(ctx->opcode) == 0) {
529
        /* lis case */
488 530
        gen_op_set_T0(simm << 16);
489 531
    } else {
490 532
        gen_op_load_gpr_T0(rA(ctx->opcode));
491
        gen_op_addi(simm << 16);
533
        if (likely(simm != 0))
534
            gen_op_addi(simm << 16);
492 535
    }
493 536
    gen_op_store_T0_gpr(rD(ctx->opcode));
494 537
}
......
543 586
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
544 587
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
545 588
    gen_op_##name();                                                          \
546
    if (Rc(ctx->opcode) != 0)                                                 \
547
        gen_op_set_Rc0();                                                     \
548 589
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
590
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
591
        gen_set_Rc0(ctx);                                                     \
549 592
}
550 593
#define GEN_LOGICAL2(name, opc)                                               \
551 594
__GEN_LOGICAL2(name, 0x1C, opc)
......
555 598
{                                                                             \
556 599
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
557 600
    gen_op_##name();                                                          \
558
    if (Rc(ctx->opcode) != 0)                                                 \
559
        gen_op_set_Rc0();                                                     \
560 601
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
602
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
603
        gen_set_Rc0(ctx);                                                     \
561 604
}
562 605

  
563 606
/* and & and. */
......
568 611
GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
569 612
{
570 613
    gen_op_load_gpr_T0(rS(ctx->opcode));
571
    gen_op_andi_(UIMM(ctx->opcode));
572
    gen_op_set_Rc0();
614
    gen_op_andi_T0(UIMM(ctx->opcode));
573 615
    gen_op_store_T0_gpr(rA(ctx->opcode));
616
    gen_set_Rc0(ctx);
574 617
}
575 618
/* andis. */
576 619
GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
577 620
{
578 621
    gen_op_load_gpr_T0(rS(ctx->opcode));
579
    gen_op_andi_(UIMM(ctx->opcode) << 16);
580
    gen_op_set_Rc0();
622
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
581 623
    gen_op_store_T0_gpr(rA(ctx->opcode));
624
    gen_set_Rc0(ctx);
582 625
}
583 626

  
584 627
/* cntlzw */
......
597 640
/* or & or. */
598 641
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
599 642
{
600
    gen_op_load_gpr_T0(rS(ctx->opcode));
601
    /* Optimisation for mr case */
602
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
603
        gen_op_load_gpr_T1(rB(ctx->opcode));
604
        gen_op_or();
643
    int rs, ra, rb;
644

  
645
    rs = rS(ctx->opcode);
646
    ra = rA(ctx->opcode);
647
    rb = rB(ctx->opcode);
648
    /* Optimisation for mr. ri case */
649
    if (rs != ra || rs != rb) {
650
        gen_op_load_gpr_T0(rs);
651
        if (rs != rb) {
652
            gen_op_load_gpr_T1(rb);
653
            gen_op_or();
654
        }
655
        gen_op_store_T0_gpr(ra);
656
        if (unlikely(Rc(ctx->opcode) != 0))
657
            gen_set_Rc0(ctx);
658
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
659
        gen_op_load_gpr_T0(rs);
660
        gen_set_Rc0(ctx);
605 661
    }
606
    if (Rc(ctx->opcode) != 0)
607
        gen_op_set_Rc0();
608
    gen_op_store_T0_gpr(rA(ctx->opcode));
609 662
}
610 663

  
611 664
/* orc & orc. */
......
619 672
        gen_op_load_gpr_T1(rB(ctx->opcode));
620 673
        gen_op_xor();
621 674
    } else {
622
        gen_op_set_T0(0);
675
        gen_op_reset_T0();
623 676
    }
624
    if (Rc(ctx->opcode) != 0)
625
        gen_op_set_Rc0();
626 677
    gen_op_store_T0_gpr(rA(ctx->opcode));
678
    if (unlikely(Rc(ctx->opcode) != 0))
679
        gen_set_Rc0(ctx);
627 680
}
628 681
/* ori */
629 682
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
630 683
{
631
    uint32_t uimm = UIMM(ctx->opcode);
684
    target_ulong uimm = UIMM(ctx->opcode);
632 685

  
633 686
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
634 687
        /* NOP */
688
        /* XXX: should handle special NOPs for POWER series */
635 689
        return;
636
        }
637
        gen_op_load_gpr_T0(rS(ctx->opcode));
638
    if (uimm != 0)
690
    }
691
    gen_op_load_gpr_T0(rS(ctx->opcode));
692
    if (likely(uimm != 0))
639 693
        gen_op_ori(uimm);
640
        gen_op_store_T0_gpr(rA(ctx->opcode));
694
    gen_op_store_T0_gpr(rA(ctx->opcode));
641 695
}
642 696
/* oris */
643 697
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
644 698
{
645
    uint32_t uimm = UIMM(ctx->opcode);
699
    target_ulong uimm = UIMM(ctx->opcode);
646 700

  
647 701
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
648 702
        /* NOP */
649 703
        return;
650
        }
651
        gen_op_load_gpr_T0(rS(ctx->opcode));
652
    if (uimm != 0)
704
    }
705
    gen_op_load_gpr_T0(rS(ctx->opcode));
706
    if (likely(uimm != 0))
653 707
        gen_op_ori(uimm << 16);
654
        gen_op_store_T0_gpr(rA(ctx->opcode));
708
    gen_op_store_T0_gpr(rA(ctx->opcode));
655 709
}
656 710
/* xori */
657 711
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
658 712
{
659
    uint32_t uimm = UIMM(ctx->opcode);
713
    target_ulong uimm = UIMM(ctx->opcode);
660 714

  
661 715
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
662 716
        /* NOP */
663 717
        return;
664 718
    }
665 719
    gen_op_load_gpr_T0(rS(ctx->opcode));
666
    if (uimm != 0)
667
    gen_op_xori(uimm);
720
    if (likely(uimm != 0))
721
        gen_op_xori(uimm);
668 722
    gen_op_store_T0_gpr(rA(ctx->opcode));
669 723
}
670 724

  
671 725
/* xoris */
672 726
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
673 727
{
674
    uint32_t uimm = UIMM(ctx->opcode);
728
    target_ulong uimm = UIMM(ctx->opcode);
675 729

  
676 730
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
677 731
        /* NOP */
678 732
        return;
679 733
    }
680 734
    gen_op_load_gpr_T0(rS(ctx->opcode));
681
    if (uimm != 0)
682
    gen_op_xori(uimm << 16);
735
    if (likely(uimm != 0))
736
        gen_op_xori(uimm << 16);
683 737
    gen_op_store_T0_gpr(rA(ctx->opcode));
684 738
}
685 739

  
......
687 741
/* rlwimi & rlwimi. */
688 742
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
689 743
{
690
    uint32_t mb, me;
744
    target_ulong mask;
745
    uint32_t mb, me, sh;
746
    int n;
691 747

  
692 748
    mb = MB(ctx->opcode);
693 749
    me = ME(ctx->opcode);
750
    sh = SH(ctx->opcode);
751
    n = me + 1 - mb;
752
    if (likely(sh == 0)) {
753
        if (likely(mb == 0 && me == 31)) {
754
            gen_op_load_gpr_T0(rS(ctx->opcode));
755
            goto do_store;
756
        } else if (likely(mb == 31 && me == 0)) {
757
            gen_op_load_gpr_T0(rA(ctx->opcode));
758
            goto do_store;
759
        }
760
        gen_op_load_gpr_T0(rS(ctx->opcode));
761
        gen_op_load_gpr_T1(rA(ctx->opcode));
762
        goto do_mask;
763
    }
694 764
    gen_op_load_gpr_T0(rS(ctx->opcode));
695 765
    gen_op_load_gpr_T1(rA(ctx->opcode));
696
    gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me));
697
    if (Rc(ctx->opcode) != 0)
698
        gen_op_set_Rc0();
766
    gen_op_rotli32_T0(SH(ctx->opcode));
767
 do_mask:
768
#if defined(TARGET_PPC64)
769
    mb += 32;
770
    me += 32;
771
#endif
772
    mask = MASK(mb, me);
773
    gen_op_andi_T0(mask);
774
    gen_op_andi_T1(~mask);
775
    gen_op_or();
776
 do_store:
699 777
    gen_op_store_T0_gpr(rA(ctx->opcode));
778
    if (unlikely(Rc(ctx->opcode) != 0))
779
        gen_set_Rc0(ctx);
700 780
}
701 781
/* rlwinm & rlwinm. */
702 782
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
......
707 787
    mb = MB(ctx->opcode);
708 788
    me = ME(ctx->opcode);
709 789
    gen_op_load_gpr_T0(rS(ctx->opcode));
710
#if 1 // TRY
711
    if (sh == 0) {
712
        gen_op_andi_(MASK(mb, me));
713
        goto store;
714
    }
715
#endif
716
    if (mb == 0) {
717
        if (me == 31) {
718
            gen_op_rotlwi(sh);
719
            goto store;
720
#if 0
721
        } else if (me == (31 - sh)) {
722
            gen_op_slwi(sh);
723
            goto store;
724
#endif
790
    if (likely(sh == 0)) {
791
        goto do_mask;
792
    }
793
    if (likely(mb == 0)) {
794
        if (likely(me == 31)) {
795
            gen_op_rotli32_T0(sh);
796
            goto do_store;
797
        } else if (likely(me == (31 - sh))) {
798
            gen_op_sli_T0(sh);
799
            goto do_store;
725 800
        }
726
    } else if (me == 31) {
727
#if 0
728
        if (sh == (32 - mb)) {
729
            gen_op_srwi(mb);
730
            goto store;
801
    } else if (likely(me == 31)) {
802
        if (likely(sh == (32 - mb))) {
803
            gen_op_srli_T0(mb);
804
            goto do_store;
731 805
        }
732
#endif
733 806
    }
734
    gen_op_rlwinm(sh, MASK(mb, me));
735
store:
736
    if (Rc(ctx->opcode) != 0)
737
        gen_op_set_Rc0();
807
    gen_op_rotli32_T0(sh);
808
 do_mask:
809
#if defined(TARGET_PPC64)
810
    mb += 32;
811
    me += 32;
812
#endif
813
    gen_op_andi_T0(MASK(mb, me));
814
 do_store:
738 815
    gen_op_store_T0_gpr(rA(ctx->opcode));
816
    if (unlikely(Rc(ctx->opcode) != 0))
817
        gen_set_Rc0(ctx);
739 818
}
740 819
/* rlwnm & rlwnm. */
741 820
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
......
746 825
    me = ME(ctx->opcode);
747 826
    gen_op_load_gpr_T0(rS(ctx->opcode));
748 827
    gen_op_load_gpr_T1(rB(ctx->opcode));
749
    if (mb == 0 && me == 31) {
750
        gen_op_rotl();
751
    } else
752
    {
753
        gen_op_rlwnm(MASK(mb, me));
828
    gen_op_rotl32_T0_T1();
829
    if (unlikely(mb != 0 || me != 31)) {
830
#if defined(TARGET_PPC64)
831
        mb += 32;
832
        me += 32;
833
#endif
834
        gen_op_andi_T0(MASK(mb, me));
754 835
    }
755
    if (Rc(ctx->opcode) != 0)
756
        gen_op_set_Rc0();
757 836
    gen_op_store_T0_gpr(rA(ctx->opcode));
837
    if (unlikely(Rc(ctx->opcode) != 0))
838
        gen_set_Rc0(ctx);
758 839
}
759 840

  
760 841
/***                             Integer shift                             ***/
......
767 848
{
768 849
    gen_op_load_gpr_T0(rS(ctx->opcode));
769 850
    if (SH(ctx->opcode) != 0)
770
    gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
771
    if (Rc(ctx->opcode) != 0)
772
        gen_op_set_Rc0();
851
        gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
773 852
    gen_op_store_T0_gpr(rA(ctx->opcode));
853
    if (unlikely(Rc(ctx->opcode) != 0))
854
        gen_set_Rc0(ctx);
774 855
}
775 856
/* srw & srw. */
776 857
__GEN_LOGICAL2(srw, 0x18, 0x10);
......
779 860
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat)                           \
780 861
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT)                   \
781 862
{                                                                             \
782
    if (!ctx->fpu_enabled) {                                                  \
863
    if (unlikely(!ctx->fpu_enabled)) {                                        \
783 864
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
784 865
        return;                                                               \
785 866
    }                                                                         \
......
792 873
        gen_op_frsp();                                                        \
793 874
    }                                                                         \
794 875
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
795
    if (Rc(ctx->opcode))                                                      \
876
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
796 877
        gen_op_set_Rc1();                                                     \
797 878
}
798 879

  
......
803 884
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
804 885
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
805 886
{                                                                             \
806
    if (!ctx->fpu_enabled) {                                                  \
887
    if (unlikely(!ctx->fpu_enabled)) {                                        \
807 888
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
808 889
        return;                                                               \
809 890
    }                                                                         \
......
815 896
        gen_op_frsp();                                                        \
816 897
    }                                                                         \
817 898
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
818
    if (Rc(ctx->opcode))                                                      \
899
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
819 900
        gen_op_set_Rc1();                                                     \
820 901
}
821 902
#define GEN_FLOAT_AB(name, op2, inval)                                        \
......
825 906
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
826 907
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
827 908
{                                                                             \
828
    if (!ctx->fpu_enabled) {                                                  \
909
    if (unlikely(!ctx->fpu_enabled)) {                                        \
829 910
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
830 911
        return;                                                               \
831 912
    }                                                                         \
......
837 918
        gen_op_frsp();                                                        \
838 919
    }                                                                         \
839 920
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
840
    if (Rc(ctx->opcode))                                                      \
921
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
841 922
        gen_op_set_Rc1();                                                     \
842 923
}
843 924
#define GEN_FLOAT_AC(name, op2, inval)                                        \
......
847 928
#define GEN_FLOAT_B(name, op2, op3)                                           \
848 929
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT)                   \
849 930
{                                                                             \
850
    if (!ctx->fpu_enabled) {                                                  \
931
    if (unlikely(!ctx->fpu_enabled)) {                                        \
851 932
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
852 933
        return;                                                               \
853 934
    }                                                                         \
......
855 936
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
856 937
    gen_op_f##name();                                                         \
857 938
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
858
    if (Rc(ctx->opcode))                                                      \
939
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
859 940
        gen_op_set_Rc1();                                                     \
860 941
}
861 942

  
862 943
#define GEN_FLOAT_BS(name, op1, op2)                                          \
863 944
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT)                   \
864 945
{                                                                             \
865
    if (!ctx->fpu_enabled) {                                                  \
946
    if (unlikely(!ctx->fpu_enabled)) {                                        \
866 947
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
867 948
        return;                                                               \
868 949
    }                                                                         \
......
870 951
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
871 952
    gen_op_f##name();                                                         \
872 953
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
873
    if (Rc(ctx->opcode))                                                      \
954
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
874 955
        gen_op_set_Rc1();                                                     \
875 956
}
876 957

  
......
881 962
/* fmul - fmuls */
882 963
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
883 964

  
884
/* fres */
965
/* fres */ /* XXX: not in 601 */
885 966
GEN_FLOAT_BS(res, 0x3B, 0x18);
886 967

  
887
/* frsqrte */
968
/* frsqrte */ /* XXX: not in 601 */
888 969
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
889 970

  
890
/* fsel */
971
/* fsel */ /* XXX: not in 601 */
891 972
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0);
892 973
/* fsub - fsubs */
893 974
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
......
895 976
/* fsqrt */
896 977
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
897 978
{
898
    if (!ctx->fpu_enabled) {
979
    if (unlikely(!ctx->fpu_enabled)) {
899 980
        RET_EXCP(ctx, EXCP_NO_FP, 0);
900 981
        return;
901 982
    }
......
903 984
    gen_op_load_fpr_FT0(rB(ctx->opcode));
904 985
    gen_op_fsqrt();
905 986
    gen_op_store_FT0_fpr(rD(ctx->opcode));
906
    if (Rc(ctx->opcode))
987
    if (unlikely(Rc(ctx->opcode) != 0))
907 988
        gen_op_set_Rc1();
908 989
}
909 990

  
910 991
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
911 992
{
912
    if (!ctx->fpu_enabled) {
993
    if (unlikely(!ctx->fpu_enabled)) {
913 994
        RET_EXCP(ctx, EXCP_NO_FP, 0);
914 995
        return;
915 996
    }
......
918 999
    gen_op_fsqrt();
919 1000
    gen_op_frsp();
920 1001
    gen_op_store_FT0_fpr(rD(ctx->opcode));
921
    if (Rc(ctx->opcode))
1002
    if (unlikely(Rc(ctx->opcode) != 0))
922 1003
        gen_op_set_Rc1();
923 1004
}
924 1005

  
......
942 1023

  
943 1024
/***                         Floating-Point compare                        ***/
944 1025
/* fcmpo */
945
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1026
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
946 1027
{
947
    if (!ctx->fpu_enabled) {
1028
    if (unlikely(!ctx->fpu_enabled)) {
948 1029
        RET_EXCP(ctx, EXCP_NO_FP, 0);
949 1030
        return;
950 1031
    }
......
956 1037
}
957 1038

  
958 1039
/* fcmpu */
959
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1040
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
960 1041
{
961
    if (!ctx->fpu_enabled) {
1042
    if (unlikely(!ctx->fpu_enabled)) {
962 1043
        RET_EXCP(ctx, EXCP_NO_FP, 0);
963 1044
        return;
964 1045
    }
......
976 1057
/* fmr  - fmr. */
977 1058
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
978 1059
{
979
    if (!ctx->fpu_enabled) {
1060
    if (unlikely(!ctx->fpu_enabled)) {
980 1061
        RET_EXCP(ctx, EXCP_NO_FP, 0);
981 1062
        return;
982 1063
    }
983 1064
    gen_op_reset_scrfx();
984 1065
    gen_op_load_fpr_FT0(rB(ctx->opcode));
985 1066
    gen_op_store_FT0_fpr(rD(ctx->opcode));
986
    if (Rc(ctx->opcode))
1067
    if (unlikely(Rc(ctx->opcode) != 0))
987 1068
        gen_op_set_Rc1();
988 1069
}
989 1070

  
......
996 1077
/* mcrfs */
997 1078
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
998 1079
{
999
    if (!ctx->fpu_enabled) {
1080
    if (unlikely(!ctx->fpu_enabled)) {
1000 1081
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1001 1082
        return;
1002 1083
    }
......
1008 1089
/* mffs */
1009 1090
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1010 1091
{
1011
    if (!ctx->fpu_enabled) {
1092
    if (unlikely(!ctx->fpu_enabled)) {
1012 1093
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1013 1094
        return;
1014 1095
    }
1015 1096
    gen_op_load_fpscr();
1016 1097
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1017
    if (Rc(ctx->opcode))
1098
    if (unlikely(Rc(ctx->opcode) != 0))
1018 1099
        gen_op_set_Rc1();
1019 1100
}
1020 1101

  
......
1023 1104
{
1024 1105
    uint8_t crb;
1025 1106
    
1026
    if (!ctx->fpu_enabled) {
1107
    if (unlikely(!ctx->fpu_enabled)) {
1027 1108
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1028 1109
        return;
1029 1110
    }
1030 1111
    crb = crbD(ctx->opcode) >> 2;
1031 1112
    gen_op_load_fpscr_T0(crb);
1032
    gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03)));
1113
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1033 1114
    gen_op_store_T0_fpscr(crb);
1034
    if (Rc(ctx->opcode))
1115
    if (unlikely(Rc(ctx->opcode) != 0))
1035 1116
        gen_op_set_Rc1();
1036 1117
}
1037 1118

  
......
1040 1121
{
1041 1122
    uint8_t crb;
1042 1123
    
1043
    if (!ctx->fpu_enabled) {
1124
    if (unlikely(!ctx->fpu_enabled)) {
1044 1125
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1045 1126
        return;
1046 1127
    }
......
1048 1129
    gen_op_load_fpscr_T0(crb);
1049 1130
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1050 1131
    gen_op_store_T0_fpscr(crb);
1051
    if (Rc(ctx->opcode))
1132
    if (unlikely(Rc(ctx->opcode) != 0))
1052 1133
        gen_op_set_Rc1();
1053 1134
}
1054 1135

  
1055 1136
/* mtfsf */
1056 1137
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1057 1138
{
1058
    if (!ctx->fpu_enabled) {
1139
    if (unlikely(!ctx->fpu_enabled)) {
1059 1140
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1060 1141
        return;
1061 1142
    }
1062 1143
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1063 1144
    gen_op_store_fpscr(FM(ctx->opcode));
1064
    if (Rc(ctx->opcode))
1145
    if (unlikely(Rc(ctx->opcode) != 0))
1065 1146
        gen_op_set_Rc1();
1066 1147
}
1067 1148

  
1068 1149
/* mtfsfi */
1069 1150
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1070 1151
{
1071
    if (!ctx->fpu_enabled) {
1152
    if (unlikely(!ctx->fpu_enabled)) {
1072 1153
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1073 1154
        return;
1074 1155
    }
1075 1156
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1076
    if (Rc(ctx->opcode))
1157
    if (unlikely(Rc(ctx->opcode) != 0))
1077 1158
        gen_op_set_Rc1();
1078 1159
}
1079 1160

  
1161
/***                           Addressing modes                            ***/
1162
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1163
static inline void gen_addr_imm_index (DisasContext *ctx)
1164
{
1165
    target_long simm = SIMM(ctx->opcode);
1166

  
1167
    if (rA(ctx->opcode) == 0) {
1168
        gen_op_set_T0(simm);
1169
    } else {
1170
        gen_op_load_gpr_T0(rA(ctx->opcode));
1171
        if (likely(simm != 0))
1172
            gen_op_addi(simm);
1173
    }
1174
}
1175

  
1176
static inline void gen_addr_reg_index (DisasContext *ctx)
1177
{
1178
    if (rA(ctx->opcode) == 0) {
1179
        gen_op_load_gpr_T0(rB(ctx->opcode));
1180
    } else {
1181
        gen_op_load_gpr_T0(rA(ctx->opcode));
1182
        gen_op_load_gpr_T1(rB(ctx->opcode));
1183
        gen_op_add();
1184
    }
1185
}
1186

  
1187
static inline void gen_addr_register (DisasContext *ctx)
1188
{
1189
    if (rA(ctx->opcode) == 0) {
1190
        gen_op_reset_T0();
1191
    } else {
1192
        gen_op_load_gpr_T0(rA(ctx->opcode));
1193
    }
1194
}
1195

  
1080 1196
/***                             Integer load                              ***/
1081 1197
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1082 1198
#if defined(CONFIG_USER_ONLY)
......
1118 1234
#define GEN_LD(width, opc)                                                    \
1119 1235
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)               \
1120 1236
{                                                                             \
1121
    uint32_t simm = SIMM(ctx->opcode);                                        \
1122
    if (rA(ctx->opcode) == 0) {                                               \
1123
        gen_op_set_T0(simm);                                                  \
1124
    } else {                                                                  \
1125
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1126
        if (simm != 0)                                                        \
1127
            gen_op_addi(simm);                                                \
1128
    }                                                                         \
1237
    gen_addr_imm_index(ctx);                                                  \
1129 1238
    op_ldst(l##width);                                                        \
1130 1239
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1131 1240
}
......
1133 1242
#define GEN_LDU(width, opc)                                                   \
1134 1243
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)            \
1135 1244
{                                                                             \
1136
    uint32_t simm = SIMM(ctx->opcode);                                        \
1137
    if (rA(ctx->opcode) == 0 ||                                               \
1138
        rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1245
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1246
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1139 1247
        RET_INVAL(ctx);                                                       \
1140 1248
        return;                                                               \
1141 1249
    }                                                                         \
1142
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1143
    if (simm != 0)                                                            \
1144
        gen_op_addi(simm);                                                    \
1250
    gen_addr_imm_index(ctx);                                                  \
1145 1251
    op_ldst(l##width);                                                        \
1146 1252
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1147 1253
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
......
1150 1256
#define GEN_LDUX(width, opc)                                                  \
1151 1257
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)           \
1152 1258
{                                                                             \
1153
    if (rA(ctx->opcode) == 0 ||                                               \
1154
        rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1259
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1260
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1155 1261
        RET_INVAL(ctx);                                                       \
1156 1262
        return;                                                               \
1157 1263
    }                                                                         \
1158
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1159
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1160
    gen_op_add();                                                             \
1264
    gen_addr_reg_index(ctx);                                                  \
1161 1265
    op_ldst(l##width);                                                        \
1162 1266
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1163 1267
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
......
1166 1270
#define GEN_LDX(width, opc2, opc3)                                            \
1167 1271
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)           \
1168 1272
{                                                                             \
1169
    if (rA(ctx->opcode) == 0) {                                               \
1170
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1171
    } else {                                                                  \
1172
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1173
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1174
        gen_op_add();                                                         \
1175
    }                                                                         \
1273
    gen_addr_reg_index(ctx);                                                  \
1176 1274
    op_ldst(l##width);                                                        \
1177 1275
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1178 1276
}
......
1197 1295
#define GEN_ST(width, opc)                                                    \
1198 1296
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)              \
1199 1297
{                                                                             \
1200
    uint32_t simm = SIMM(ctx->opcode);                                        \
1201
    if (rA(ctx->opcode) == 0) {                                               \
1202
        gen_op_set_T0(simm);                                                  \
1203
    } else {                                                                  \
1204
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1205
        if (simm != 0)                                                        \
1206
            gen_op_addi(simm);                                                \
1207
    }                                                                         \
1298
    gen_addr_imm_index(ctx);                                                  \
1208 1299
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1209 1300
    op_ldst(st##width);                                                       \
1210 1301
}
......
1212 1303
#define GEN_STU(width, opc)                                                   \
1213 1304
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)           \
1214 1305
{                                                                             \
1215
    uint32_t simm = SIMM(ctx->opcode);                                        \
1216
    if (rA(ctx->opcode) == 0) {                                               \
1306
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1217 1307
        RET_INVAL(ctx);                                                       \
1218 1308
        return;                                                               \
1219 1309
    }                                                                         \
1220
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1221
    if (simm != 0)                                                            \
1222
        gen_op_addi(simm);                                                    \
1310
    gen_addr_imm_index(ctx);                                                  \
1223 1311
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1224 1312
    op_ldst(st##width);                                                       \
1225 1313
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
......
1228 1316
#define GEN_STUX(width, opc)                                                  \
1229 1317
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
1230 1318
{                                                                             \
1231
    if (rA(ctx->opcode) == 0) {                                               \
1319
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1232 1320
        RET_INVAL(ctx);                                                       \
1233 1321
        return;                                                               \
1234 1322
    }                                                                         \
1235
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1236
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1237
    gen_op_add();                                                             \
1323
    gen_addr_reg_index(ctx);                                                  \
1238 1324
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1239 1325
    op_ldst(st##width);                                                       \
1240 1326
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
......
1243 1329
#define GEN_STX(width, opc2, opc3)                                            \
1244 1330
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)          \
1245 1331
{                                                                             \
1246
    if (rA(ctx->opcode) == 0) {                                               \
1247
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1248
    } else {                                                                  \
1249
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1250
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1251
        gen_op_add();                                                         \
1252
    }                                                                         \
1332
    gen_addr_reg_index(ctx);                                                  \
1253 1333
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1254 1334
    op_ldst(st##width);                                                       \
1255 1335
}
......
1311 1391
/* lmw */
1312 1392
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1313 1393
{
1314
    int simm = SIMM(ctx->opcode);
1315

  
1316
    if (rA(ctx->opcode) == 0) {
1317
        gen_op_set_T0(simm);
1318
    } else {
1319
        gen_op_load_gpr_T0(rA(ctx->opcode));
1320
        if (simm != 0)
1321
            gen_op_addi(simm);
1322
    }
1394
    /* NIP cannot be restored if the memory exception comes from an helper */
1395
    gen_op_update_nip(ctx->nip - 4);
1396
    gen_addr_imm_index(ctx);
1323 1397
    op_ldstm(lmw, rD(ctx->opcode));
1324 1398
}
1325 1399

  
1326 1400
/* stmw */
1327 1401
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1328 1402
{
1329
    int simm = SIMM(ctx->opcode);
1330

  
1331
    if (rA(ctx->opcode) == 0) {
1332
        gen_op_set_T0(simm);
1333
    } else {
1334
        gen_op_load_gpr_T0(rA(ctx->opcode));
1335
        if (simm != 0)
1336
            gen_op_addi(simm);
1337
    }
1403
    /* NIP cannot be restored if the memory exception comes from an helper */
1404
    gen_op_update_nip(ctx->nip - 4);
1405
    gen_addr_imm_index(ctx);
1338 1406
    op_ldstm(stmw, rS(ctx->opcode));
1339 1407
}
1340 1408

  
......
1391 1459
    if (nb == 0)
1392 1460
        nb = 32;
1393 1461
    nr = nb / 4;
1394
    if (((start + nr) > 32  && start <= ra && (start + nr - 32) > ra) ||
1395
        ((start + nr) <= 32 && start <= ra && (start + nr) > ra)) {
1462
    if (unlikely(((start + nr) > 32  &&
1463
                  start <= ra && (start + nr - 32) > ra) ||
1464
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
1396 1465
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
1397 1466
        return;
1398 1467
    }
1399
    if (ra == 0) {
1400
        gen_op_set_T0(0);
1401
    } else {
1402
        gen_op_load_gpr_T0(ra);
1403
    }
1404
    gen_op_set_T1(nb);
1405 1468
    /* NIP cannot be restored if the memory exception comes from an helper */
1406
    gen_op_update_nip((ctx)->nip - 4); 
1469
    gen_op_update_nip(ctx->nip - 4);
1470
    gen_addr_register(ctx);
1471
    gen_op_set_T1(nb);
1407 1472
    op_ldsts(lswi, start);
1408 1473
}
1409 1474

  
......
1413 1478
    int ra = rA(ctx->opcode);
1414 1479
    int rb = rB(ctx->opcode);
1415 1480

  
1481
    /* NIP cannot be restored if the memory exception comes from an helper */
1482
    gen_op_update_nip(ctx->nip - 4);
1483
    gen_addr_reg_index(ctx);
1416 1484
    if (ra == 0) {
1417
        gen_op_load_gpr_T0(rb);
1418 1485
        ra = rb;
1419
    } else {
1420
        gen_op_load_gpr_T0(ra);
1421
        gen_op_load_gpr_T1(rb);
1422
        gen_op_add();
1423 1486
    }
1424 1487
    gen_op_load_xer_bc();
1425
    /* NIP cannot be restored if the memory exception comes from an helper */
1426
    gen_op_update_nip((ctx)->nip - 4); 
1427 1488
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
1428 1489
}
1429 1490

  
......
1432 1493
{
1433 1494
    int nb = NB(ctx->opcode);
1434 1495

  
1435
    if (rA(ctx->opcode) == 0) {
1436
        gen_op_set_T0(0);
1437
    } else {
1438
        gen_op_load_gpr_T0(rA(ctx->opcode));
1439
    }
1496
    /* NIP cannot be restored if the memory exception comes from an helper */
1497
    gen_op_update_nip(ctx->nip - 4);
1498
    gen_addr_register(ctx);
1440 1499
    if (nb == 0)
1441 1500
        nb = 32;
1442 1501
    gen_op_set_T1(nb);
1443
    /* NIP cannot be restored if the memory exception comes from an helper */
1444
    gen_op_update_nip((ctx)->nip - 4); 
1445 1502
    op_ldsts(stsw, rS(ctx->opcode));
1446 1503
}
1447 1504

  
1448 1505
/* stswx */
1449 1506
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
1450 1507
{
1451
    int ra = rA(ctx->opcode);
1452

  
1453
    if (ra == 0) {
1454
        gen_op_load_gpr_T0(rB(ctx->opcode));
1455
        ra = rB(ctx->opcode);
1456
    } else {
1457
        gen_op_load_gpr_T0(ra);
1458
        gen_op_load_gpr_T1(rB(ctx->opcode));
1459
        gen_op_add();
1460
    }
1461
    gen_op_load_xer_bc();
1462 1508
    /* NIP cannot be restored if the memory exception comes from an helper */
1463
    gen_op_update_nip((ctx)->nip - 4); 
1509
    gen_op_update_nip(ctx->nip - 4); 
1510
    gen_addr_reg_index(ctx);
1511
    gen_op_load_xer_bc();
1464 1512
    op_ldsts(stsw, rS(ctx->opcode));
1465 1513
}
1466 1514

  
1467 1515
/***                        Memory synchronisation                         ***/
1468 1516
/* eieio */
1469
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM)
1517
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
1470 1518
{
1471 1519
}
1472 1520

  
1473 1521
/* isync */
1474
GEN_HANDLER(isync, 0x13, 0x16, 0xFF, 0x03FF0801, PPC_MEM)
1522
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
1475 1523
{
1476 1524
}
1477 1525

  
......
1502 1550
#endif
1503 1551

  
1504 1552
/* lwarx */
1505
GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_RES)
1553
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
1506 1554
{
1507
    if (rA(ctx->opcode) == 0) {
1508
        gen_op_load_gpr_T0(rB(ctx->opcode));
1509
    } else {
1510
        gen_op_load_gpr_T0(rA(ctx->opcode));
1511
        gen_op_load_gpr_T1(rB(ctx->opcode));
1512
        gen_op_add();
1513
    }
1555
    gen_addr_reg_index(ctx);
1514 1556
    op_lwarx();
1515 1557
    gen_op_store_T1_gpr(rD(ctx->opcode));
1516 1558
}
......
1518 1560
/* stwcx. */
1519 1561
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
1520 1562
{
1521
        if (rA(ctx->opcode) == 0) {
1522
            gen_op_load_gpr_T0(rB(ctx->opcode));
1523
        } else {
1524
            gen_op_load_gpr_T0(rA(ctx->opcode));
1525
            gen_op_load_gpr_T1(rB(ctx->opcode));
1526
        gen_op_add();
1527
        }
1563
    gen_addr_reg_index(ctx);
1528 1564
    gen_op_load_gpr_T1(rS(ctx->opcode));
1529 1565
    op_stwcx();
1530 1566
}
1531 1567

  
1532 1568
/* sync */
1533
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM)
1569
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
1534 1570
{
1535 1571
}
1536 1572

  
......
1538 1574
#define GEN_LDF(width, opc)                                                   \
1539 1575
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                 \
1540 1576
{                                                                             \
1541
    uint32_t simm = SIMM(ctx->opcode);                                        \
1542
    if (!ctx->fpu_enabled) {                                                  \
1577
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1543 1578
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1544 1579
        return;                                                               \
1545 1580
    }                                                                         \
1546
    if (rA(ctx->opcode) == 0) {                                               \
1547
        gen_op_set_T0(simm);                                                  \
1548
    } else {                                                                  \
1549
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1550
        if (simm != 0)                                                        \
1551
            gen_op_addi(simm);                                                \
1552
    }                                                                         \
1581
    gen_addr_imm_index(ctx);                                                  \
1553 1582
    op_ldst(l##width);                                                        \
1554
    gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1583
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1555 1584
}
1556 1585

  
1557 1586
#define GEN_LDUF(width, opc)                                                  \
1558 1587
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)              \
1559 1588
{                                                                             \
1560
    uint32_t simm = SIMM(ctx->opcode);                                        \
1561
    if (!ctx->fpu_enabled) {                                                  \
1589
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1562 1590
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1563 1591
        return;                                                               \
1564 1592
    }                                                                         \
1565
    if (rA(ctx->opcode) == 0 ||                                               \
1566
        rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1593
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1567 1594
        RET_INVAL(ctx);                                                       \
1568 1595
        return;                                                               \
1569 1596
    }                                                                         \
1570
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1571
    if (simm != 0)                                                            \
1572
        gen_op_addi(simm);                                                    \
1597
    gen_addr_imm_index(ctx);                                                  \
1573 1598
    op_ldst(l##width);                                                        \
1574
    gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1599
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1575 1600
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1576 1601
}
1577 1602

  
1578 1603
#define GEN_LDUXF(width, opc)                                                 \
1579 1604
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
1580 1605
{                                                                             \
1581
    if (!ctx->fpu_enabled) {                                                  \
1606
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1582 1607
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1583 1608
        return;                                                               \
1584 1609
    }                                                                         \
1585
    if (rA(ctx->opcode) == 0 ||                                               \
1586
        rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1610
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1587 1611
        RET_INVAL(ctx);                                                       \
1588 1612
        return;                                                               \
1589 1613
    }                                                                         \
1590
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1591
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1592
    gen_op_add();                                                             \
1614
    gen_addr_reg_index(ctx);                                                  \
1593 1615
    op_ldst(l##width);                                                        \
1594
    gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1616
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1595 1617
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1596 1618
}
1597 1619

  
1598 1620
#define GEN_LDXF(width, opc2, opc3)                                           \
1599 1621
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)             \
1600 1622
{                                                                             \
1601
    if (!ctx->fpu_enabled) {                                                  \
1623
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1602 1624
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1603 1625
        return;                                                               \
1604 1626
    }                                                                         \
1605
    if (rA(ctx->opcode) == 0) {                                               \
1606
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1607
    } else {                                                                  \
1608
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1609
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1610
        gen_op_add();                                                         \
1611
    }                                                                         \
1627
    gen_addr_reg_index(ctx);                                                  \
1612 1628
    op_ldst(l##width);                                                        \
1613
    gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1629
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1614 1630
}
1615 1631

  
1616 1632
#define GEN_LDFS(width, op)                                                   \
......
1629 1645
#define GEN_STF(width, opc)                                                   \
1630 1646
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
1631 1647
{                                                                             \
1632
    uint32_t simm = SIMM(ctx->opcode);                                        \
1633
    if (!ctx->fpu_enabled) {                                                  \
1648
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1634 1649
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1635 1650
        return;                                                               \
1636 1651
    }                                                                         \
1637
    if (rA(ctx->opcode) == 0) {                                               \
1638
        gen_op_set_T0(simm);                                                  \
1639
    } else {                                                                  \
1640
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1641
        if (simm != 0)                                                        \
1642
            gen_op_addi(simm);                                                \
1643
    }                                                                         \
1644
    gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1652
    gen_addr_imm_index(ctx);                                                  \
1653
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1645 1654
    op_ldst(st##width);                                                       \
1646 1655
}
1647 1656

  
1648 1657
#define GEN_STUF(width, opc)                                                  \
1649 1658
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
1650 1659
{                                                                             \
1651
    uint32_t simm = SIMM(ctx->opcode);                                        \
1652
    if (!ctx->fpu_enabled) {                                                  \
1660
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1653 1661
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1654 1662
        return;                                                               \
1655 1663
    }                                                                         \
1656
    if (rA(ctx->opcode) == 0) {                                               \
1664
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1657 1665
        RET_INVAL(ctx);                                                       \
1658 1666
        return;                                                               \
1659 1667
    }                                                                         \
1660
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1661
    if (simm != 0)                                                            \
1662
        gen_op_addi(simm);                                                    \
1663
    gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1668
    gen_addr_imm_index(ctx);                                                  \
1669
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1664 1670
    op_ldst(st##width);                                                       \
1665 1671
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1666 1672
}
......
1668 1674
#define GEN_STUXF(width, opc)                                                 \
1669 1675
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
1670 1676
{                                                                             \
1671
    if (!ctx->fpu_enabled) {                                                  \
1677
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1672 1678
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1673 1679
        return;                                                               \
1674 1680
    }                                                                         \
1675
    if (rA(ctx->opcode) == 0) {                                               \
1681
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1676 1682
        RET_INVAL(ctx);                                                       \
1677 1683
        return;                                                               \
1678 1684
    }                                                                         \
1679
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1680
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1681
    gen_op_add();                                                             \
1682
    gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1685
    gen_addr_reg_index(ctx);                                                  \
1686
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1683 1687
    op_ldst(st##width);                                                       \
1684 1688
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1685 1689
}
......
1687 1691
#define GEN_STXF(width, opc2, opc3)                                           \
1688 1692
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)            \
1689 1693
{                                                                             \
1690
    if (!ctx->fpu_enabled) {                                                  \
1694
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1691 1695
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1692 1696
        return;                                                               \
1693 1697
    }                                                                         \
1694
    if (rA(ctx->opcode) == 0) {                                               \
1695
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1696
    } else {                                                                  \
1697
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1698
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1699
        gen_op_add();                                                         \
1700
    }                                                                         \
1701
    gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1698
    gen_addr_reg_index(ctx);                                                  \
1699
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1702 1700
    op_ldst(st##width);                                                       \
1703 1701
}
1704 1702

  
......
1718 1716
/* stfiwx */
1719 1717
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1720 1718
{
1721
    if (!ctx->fpu_enabled) {
1719
    if (unlikely(!ctx->fpu_enabled)) {
1722 1720
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1723 1721
        return;
1724 1722
    }
1723
    gen_addr_reg_index(ctx);
1724
    /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
1725 1725
    RET_INVAL(ctx);
1726 1726
}
1727 1727

  
......
1745 1745
    } else {
1746 1746
        gen_op_set_T1(dest);
1747 1747
        gen_op_b_T1();
1748
        gen_op_reset_T0();
1748 1749
        if (ctx->singlestep_enabled)
1749 1750
            gen_op_debug();
1750
        gen_op_set_T0(0);
1751 1751
        gen_op_exit_tb();
1752 1752
    }
1753 1753
}
......
1755 1755
/* b ba bl bla */
1756 1756
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1757 1757
{
1758
    uint32_t li, target;
1758
    target_ulong li, target;
1759 1759

  
1760 1760
    /* sign extend LI */
1761
    li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
1762

  
1763
    if (AA(ctx->opcode) == 0)
1761
#if defined(TARGET_PPC64)
1762
    li = ((target_long)LI(ctx->opcode) << 38) >> 38;
1763
#else
1764
    li = ((target_long)LI(ctx->opcode) << 6) >> 6;
1765
#endif
1766
    if (likely(AA(ctx->opcode) == 0))
1764 1767
        target = ctx->nip + li - 4;
1765 1768
    else
1766 1769
        target = li;
......
1777 1780

  
1778 1781
static inline void gen_bcond(DisasContext *ctx, int type) 
1779 1782
{                                                                             
1780
    uint32_t target = 0;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff