Revision 74d37793

b/target-ppc/cpu.h
582 582
#endif
583 583
    /* segment registers */
584 584
    target_ulong sdr1;
585
    target_ulong sr[16];
585
    target_ulong sr[32];
586 586
    /* BATs */
587 587
    int nb_BATs;
588 588
    target_ulong DBAT[2][8];
b/target-ppc/helper.c
2110 2110
    }
2111 2111
}
2112 2112

  
2113
#if 0 // Unused
2114
target_ulong do_load_sr (CPUPPCState *env, int srnum)
2115
{
2116
    return env->sr[srnum];
2117
}
2118
#endif
2119

  
2120 2113
void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
2121 2114
{
2122 2115
#if defined (DEBUG_MMU)
b/target-ppc/helper.h
163 163
DEF_HELPER_2(efdcmpeq, i32, i64, i64)
164 164

  
165 165
#if !defined(CONFIG_USER_ONLY)
166
DEF_HELPER_1(load_6xx_tlbd, void, tl)
167
DEF_HELPER_1(load_6xx_tlbi, void, tl)
168
DEF_HELPER_1(load_74xx_tlbd, void, tl)
169
DEF_HELPER_1(load_74xx_tlbi, void, tl)
166
DEF_HELPER_1(4xx_tlbre_hi, tl, tl)
167
DEF_HELPER_1(4xx_tlbre_lo, tl, tl)
168
DEF_HELPER_2(4xx_tlbwe_hi, void, tl, tl)
169
DEF_HELPER_2(4xx_tlbwe_lo, void, tl, tl)
170
DEF_HELPER_1(4xx_tlbsx, tl, tl)
171
DEF_HELPER_2(440_tlbre, tl, i32, tl)
172
DEF_HELPER_3(440_tlbwe, void, i32, tl, tl)
173
DEF_HELPER_1(440_tlbsx, tl, tl)
174
DEF_HELPER_1(6xx_tlbd, void, tl)
175
DEF_HELPER_1(6xx_tlbi, void, tl)
176
DEF_HELPER_1(74xx_tlbd, void, tl)
177
DEF_HELPER_1(74xx_tlbi, void, tl)
178
DEF_HELPER_0(tlbia, void)
179
DEF_HELPER_1(tlbie, void, tl)
180
#if defined(TARGET_PPC64)
181
DEF_HELPER_1(load_slb, tl, tl)
182
DEF_HELPER_2(store_slb, void, tl, tl)
183
DEF_HELPER_0(slbia, void)
184
DEF_HELPER_1(slbie, void, tl)
185
#endif
186
DEF_HELPER_1(load_sr, tl, tl);
187
DEF_HELPER_2(store_sr, void, tl, tl);
170 188

  
171 189
DEF_HELPER_1(602_mfrom, tl, tl)
172 190
#endif
b/target-ppc/op.c
27 27
#include "op_helper.h"
28 28

  
29 29
#if !defined(CONFIG_USER_ONLY)
30
/* Segment registers load and store */
31
void OPPROTO op_load_sr (void)
32
{
33
    T0 = env->sr[T1];
34
    RETURN();
35
}
36

  
37
void OPPROTO op_store_sr (void)
38
{
39
    do_store_sr(env, T1, T0);
40
    RETURN();
41
}
42

  
43
#if defined(TARGET_PPC64)
44
void OPPROTO op_load_slb (void)
45
{
46
    T0 = ppc_load_slb(env, T1);
47
    RETURN();
48
}
49

  
50
void OPPROTO op_store_slb (void)
51
{
52
    ppc_store_slb(env, T1, T0);
53
    RETURN();
54
}
55
#endif /* defined(TARGET_PPC64) */
56

  
57 30
void OPPROTO op_load_sdr1 (void)
58 31
{
59 32
    T0 = env->sdr1;
......
218 191
}
219 192
#endif /* !defined(CONFIG_USER_ONLY) */
220 193

  
221
/***                             Integer shift                             ***/
222
void OPPROTO op_srli_T1 (void)
223
{
224
    T1 = (uint32_t)T1 >> PARAM1;
225
    RETURN();
226
}
227

  
228 194
/* Return from interrupt */
229 195
#if !defined(CONFIG_USER_ONLY)
230 196
/* Exception vectors */
......
243 209
}
244 210
#endif
245 211

  
246
#if !defined(CONFIG_USER_ONLY)
247
/* tlbia */
248
void OPPROTO op_tlbia (void)
249
{
250
    ppc_tlb_invalidate_all(env);
251
    RETURN();
252
}
253

  
254
/* tlbie */
255
void OPPROTO op_tlbie (void)
256
{
257
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
258
    RETURN();
259
}
260

  
261
#if defined(TARGET_PPC64)
262
void OPPROTO op_tlbie_64 (void)
263
{
264
    ppc_tlb_invalidate_one(env, T0);
265
    RETURN();
266
}
267
#endif
268

  
269
#if defined(TARGET_PPC64)
270
void OPPROTO op_slbia (void)
271
{
272
    ppc_slb_invalidate_all(env);
273
    RETURN();
274
}
275

  
276
void OPPROTO op_slbie (void)
277
{
278
    ppc_slb_invalidate_one(env, (uint32_t)T0);
279
    RETURN();
280
}
281

  
282
void OPPROTO op_slbie_64 (void)
283
{
284
    ppc_slb_invalidate_one(env, T0);
285
    RETURN();
286
}
287
#endif
288
#endif
289

  
290 212
/* 601 specific */
291 213
void OPPROTO op_load_601_rtcl (void)
292 214
{
......
338 260
}
339 261
#endif /* !defined(CONFIG_USER_ONLY) */
340 262

  
341
/* POWER instructions not implemented in PowerPC 601 */
342
#if !defined(CONFIG_USER_ONLY)
343
void OPPROTO op_POWER_mfsri (void)
344
{
345
    T1 = T0 >> 28;
346
    T0 = env->sr[T1];
347
    RETURN();
348
}
349
#endif
350

  
351
/* PowerPC 4xx specific micro-ops */
352
#if !defined(CONFIG_USER_ONLY)
353
void OPPROTO op_440_tlbre (void)
354
{
355
    do_440_tlbre(PARAM1);
356
    RETURN();
357
}
358

  
359
void OPPROTO op_440_tlbsx (void)
360
{
361
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
362
    RETURN();
363
}
364

  
365
void OPPROTO op_4xx_tlbsx_check (void)
366
{
367
    int tmp;
368

  
369
    tmp = xer_so;
370
    if ((int)T0 != -1)
371
        tmp |= 0x02;
372
    env->crf[0] = tmp;
373
    RETURN();
374
}
375

  
376
void OPPROTO op_440_tlbwe (void)
377
{
378
    do_440_tlbwe(PARAM1);
379
    RETURN();
380
}
381

  
382
void OPPROTO op_4xx_tlbre_lo (void)
383
{
384
    do_4xx_tlbre_lo();
385
    RETURN();
386
}
387

  
388
void OPPROTO op_4xx_tlbre_hi (void)
389
{
390
    do_4xx_tlbre_hi();
391
    RETURN();
392
}
393

  
394
void OPPROTO op_4xx_tlbsx (void)
395
{
396
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
397
    RETURN();
398
}
399

  
400
void OPPROTO op_4xx_tlbwe_lo (void)
401
{
402
    do_4xx_tlbwe_lo();
403
    RETURN();
404
}
405

  
406
void OPPROTO op_4xx_tlbwe_hi (void)
407
{
408
    do_4xx_tlbwe_hi();
409
    RETURN();
410
}
411
#endif
412

  
413 263
/* SPR micro-ops */
414 264
/* 440 specific */
415 265
#if !defined(CONFIG_USER_ONLY)
b/target-ppc/op_helper.c
2552 2552
    env = saved_env;
2553 2553
}
2554 2554

  
2555
/* Segment registers load and store */
2556
target_ulong helper_load_sr (target_ulong sr_num)
2557
{
2558
    return env->sr[sr_num];
2559
}
2560

  
2561
void helper_store_sr (target_ulong sr_num, target_ulong val)
2562
{
2563
    do_store_sr(env, sr_num, val);
2564
}
2565

  
2566
/* SLB management */
2567
#if defined(TARGET_PPC64)
2568
target_ulong helper_load_slb (target_ulong slb_nr)
2569
{
2570
    return ppc_load_slb(env, slb_nr);
2571
}
2572

  
2573
void helper_store_slb (target_ulong slb_nr, target_ulong rs)
2574
{
2575
    ppc_store_slb(env, slb_nr, rs);
2576
}
2577

  
2578
void helper_slbia (void)
2579
{
2580
    ppc_slb_invalidate_all(env);
2581
}
2582

  
2583
void helper_slbie (target_ulong addr)
2584
{
2585
    ppc_slb_invalidate_one(env, addr);
2586
}
2587

  
2588
#endif /* defined(TARGET_PPC64) */
2589

  
2590
/* TLB management */
2591
void helper_tlbia (void)
2592
{
2593
    ppc_tlb_invalidate_all(env);
2594
}
2595

  
2596
void helper_tlbie (target_ulong addr)
2597
{
2598
    ppc_tlb_invalidate_one(env, addr);
2599
}
2600

  
2555 2601
/* Software driven TLBs management */
2556 2602
/* PowerPC 602/603 software TLB load instructions helpers */
2557
static void helper_load_6xx_tlb (target_ulong new_EPN, int is_code)
2603
static void do_6xx_tlb (target_ulong new_EPN, int is_code)
2558 2604
{
2559 2605
    target_ulong RPN, CMP, EPN;
2560 2606
    int way;
......
2580 2626
                     way, is_code, CMP, RPN);
2581 2627
}
2582 2628

  
2583
void helper_load_6xx_tlbd (target_ulong EPN)
2629
void helper_6xx_tlbd (target_ulong EPN)
2584 2630
{
2585
    helper_load_6xx_tlb(EPN, 0);
2631
    do_6xx_tlb(EPN, 0);
2586 2632
}
2587 2633

  
2588
void helper_load_6xx_tlbi (target_ulong EPN)
2634
void helper_6xx_tlbi (target_ulong EPN)
2589 2635
{
2590
    helper_load_6xx_tlb(EPN, 1);
2636
    do_6xx_tlb(EPN, 1);
2591 2637
}
2592 2638

  
2593 2639
/* PowerPC 74xx software TLB load instructions helpers */
2594
static void helper_load_74xx_tlb (target_ulong new_EPN, int is_code)
2640
static void do_74xx_tlb (target_ulong new_EPN, int is_code)
2595 2641
{
2596 2642
    target_ulong RPN, CMP, EPN;
2597 2643
    int way;
......
2612 2658
                     way, is_code, CMP, RPN);
2613 2659
}
2614 2660

  
2615
void helper_load_74xx_tlbd (target_ulong EPN)
2661
void helper_74xx_tlbd (target_ulong EPN)
2616 2662
{
2617
    helper_load_74xx_tlb(EPN, 0);
2663
    do_74xx_tlb(EPN, 0);
2618 2664
}
2619 2665

  
2620
void helper_load_74xx_tlbi (target_ulong EPN)
2666
void helper_74xx_tlbi (target_ulong EPN)
2621 2667
{
2622
    helper_load_74xx_tlb(EPN, 1);
2668
    do_74xx_tlb(EPN, 1);
2623 2669
}
2624 2670

  
2625 2671
static always_inline target_ulong booke_tlb_to_page_size (int size)
......
2691 2737
}
2692 2738

  
2693 2739
/* Helpers for 4xx TLB management */
2694
void do_4xx_tlbre_lo (void)
2740
target_ulong helper_4xx_tlbre_lo (target_ulong entry)
2695 2741
{
2696 2742
    ppcemb_tlb_t *tlb;
2743
    target_ulong ret;
2697 2744
    int size;
2698 2745

  
2699
    T0 &= 0x3F;
2700
    tlb = &env->tlb[T0].tlbe;
2701
    T0 = tlb->EPN;
2746
    entry &= 0x3F;
2747
    tlb = &env->tlb[entry].tlbe;
2748
    ret = tlb->EPN;
2702 2749
    if (tlb->prot & PAGE_VALID)
2703
        T0 |= 0x400;
2750
        ret |= 0x400;
2704 2751
    size = booke_page_size_to_tlb(tlb->size);
2705 2752
    if (size < 0 || size > 0x7)
2706 2753
        size = 1;
2707
    T0 |= size << 7;
2754
    ret |= size << 7;
2708 2755
    env->spr[SPR_40x_PID] = tlb->PID;
2756
    return ret;
2709 2757
}
2710 2758

  
2711
void do_4xx_tlbre_hi (void)
2759
target_ulong helper_4xx_tlbre_hi (target_ulong entry)
2712 2760
{
2713 2761
    ppcemb_tlb_t *tlb;
2762
    target_ulong ret;
2714 2763

  
2715
    T0 &= 0x3F;
2716
    tlb = &env->tlb[T0].tlbe;
2717
    T0 = tlb->RPN;
2764
    entry &= 0x3F;
2765
    tlb = &env->tlb[entry].tlbe;
2766
    ret = tlb->RPN;
2718 2767
    if (tlb->prot & PAGE_EXEC)
2719
        T0 |= 0x200;
2768
        ret |= 0x200;
2720 2769
    if (tlb->prot & PAGE_WRITE)
2721
        T0 |= 0x100;
2770
        ret |= 0x100;
2771
    return ret;
2722 2772
}
2723 2773

  
2724
void do_4xx_tlbwe_hi (void)
2774
void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val)
2725 2775
{
2726 2776
    ppcemb_tlb_t *tlb;
2727 2777
    target_ulong page, end;
2728 2778

  
2729 2779
#if defined (DEBUG_SOFTWARE_TLB)
2730 2780
    if (loglevel != 0) {
2731
        fprintf(logfile, "%s T0 " TDX " T1 " TDX "\n", __func__, T0, T1);
2781
        fprintf(logfile, "%s entry " TDX " val " TDX "\n", __func__, entry, val);
2732 2782
    }
2733 2783
#endif
2734
    T0 &= 0x3F;
2735
    tlb = &env->tlb[T0].tlbe;
2784
    entry &= 0x3F;
2785
    tlb = &env->tlb[entry].tlbe;
2736 2786
    /* Invalidate previous TLB (if it's valid) */
2737 2787
    if (tlb->prot & PAGE_VALID) {
2738 2788
        end = tlb->EPN + tlb->size;
2739 2789
#if defined (DEBUG_SOFTWARE_TLB)
2740 2790
        if (loglevel != 0) {
2741 2791
            fprintf(logfile, "%s: invalidate old TLB %d start " ADDRX
2742
                    " end " ADDRX "\n", __func__, (int)T0, tlb->EPN, end);
2792
                    " end " ADDRX "\n", __func__, (int)entry, tlb->EPN, end);
2743 2793
        }
2744 2794
#endif
2745 2795
        for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
2746 2796
            tlb_flush_page(env, page);
2747 2797
    }
2748
    tlb->size = booke_tlb_to_page_size((T1 >> 7) & 0x7);
2798
    tlb->size = booke_tlb_to_page_size((val >> 7) & 0x7);
2749 2799
    /* We cannot handle TLB size < TARGET_PAGE_SIZE.
2750 2800
     * If this ever occurs, one should use the ppcemb target instead
2751 2801
     * of the ppc or ppc64 one
2752 2802
     */
2753
    if ((T1 & 0x40) && tlb->size < TARGET_PAGE_SIZE) {
2803
    if ((val & 0x40) && tlb->size < TARGET_PAGE_SIZE) {
2754 2804
        cpu_abort(env, "TLB size " TARGET_FMT_lu " < %u "
2755 2805
                  "are not supported (%d)\n",
2756
                  tlb->size, TARGET_PAGE_SIZE, (int)((T1 >> 7) & 0x7));
2806
                  tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7));
2757 2807
    }
2758
    tlb->EPN = T1 & ~(tlb->size - 1);
2759
    if (T1 & 0x40)
2808
    tlb->EPN = val & ~(tlb->size - 1);
2809
    if (val & 0x40)
2760 2810
        tlb->prot |= PAGE_VALID;
2761 2811
    else
2762 2812
        tlb->prot &= ~PAGE_VALID;
2763
    if (T1 & 0x20) {
2813
    if (val & 0x20) {
2764 2814
        /* XXX: TO BE FIXED */
2765 2815
        cpu_abort(env, "Little-endian TLB entries are not supported by now\n");
2766 2816
    }
2767 2817
    tlb->PID = env->spr[SPR_40x_PID]; /* PID */
2768
    tlb->attr = T1 & 0xFF;
2818
    tlb->attr = val & 0xFF;
2769 2819
#if defined (DEBUG_SOFTWARE_TLB)
2770 2820
    if (loglevel != 0) {
2771 2821
        fprintf(logfile, "%s: set up TLB %d RPN " PADDRX " EPN " ADDRX
......
2791 2841
    }
2792 2842
}
2793 2843

  
2794
void do_4xx_tlbwe_lo (void)
2844
void helper_4xx_tlbwe_lo (target_ulong entry, target_ulong val)
2795 2845
{
2796 2846
    ppcemb_tlb_t *tlb;
2797 2847

  
2798 2848
#if defined (DEBUG_SOFTWARE_TLB)
2799 2849
    if (loglevel != 0) {
2800
        fprintf(logfile, "%s T0 " TDX " T1 " TDX "\n", __func__, T0, T1);
2850
        fprintf(logfile, "%s entry " TDX " val " TDX "\n", __func__, entry, val);
2801 2851
    }
2802 2852
#endif
2803
    T0 &= 0x3F;
2804
    tlb = &env->tlb[T0].tlbe;
2805
    tlb->RPN = T1 & 0xFFFFFC00;
2853
    entry &= 0x3F;
2854
    tlb = &env->tlb[entry].tlbe;
2855
    tlb->RPN = val & 0xFFFFFC00;
2806 2856
    tlb->prot = PAGE_READ;
2807
    if (T1 & 0x200)
2857
    if (val & 0x200)
2808 2858
        tlb->prot |= PAGE_EXEC;
2809
    if (T1 & 0x100)
2859
    if (val & 0x100)
2810 2860
        tlb->prot |= PAGE_WRITE;
2811 2861
#if defined (DEBUG_SOFTWARE_TLB)
2812 2862
    if (loglevel != 0) {
2813 2863
        fprintf(logfile, "%s: set up TLB %d RPN " PADDRX " EPN " ADDRX
2814 2864
                " size " ADDRX " prot %c%c%c%c PID %d\n", __func__,
2815
                (int)T0, tlb->RPN, tlb->EPN, tlb->size,
2865
                (int)entry, tlb->RPN, tlb->EPN, tlb->size,
2816 2866
                tlb->prot & PAGE_READ ? 'r' : '-',
2817 2867
                tlb->prot & PAGE_WRITE ? 'w' : '-',
2818 2868
                tlb->prot & PAGE_EXEC ? 'x' : '-',
......
2821 2871
#endif
2822 2872
}
2823 2873

  
2874
target_ulong helper_4xx_tlbsx (target_ulong address)
2875
{
2876
    return ppcemb_tlb_search(env, address, env->spr[SPR_40x_PID]);
2877
}
2878

  
2824 2879
/* PowerPC 440 TLB management */
2825
void do_440_tlbwe (int word)
2880
void helper_440_tlbwe (uint32_t word, target_ulong entry, target_ulong value)
2826 2881
{
2827 2882
    ppcemb_tlb_t *tlb;
2828 2883
    target_ulong EPN, RPN, size;
......
2830 2885

  
2831 2886
#if defined (DEBUG_SOFTWARE_TLB)
2832 2887
    if (loglevel != 0) {
2833
        fprintf(logfile, "%s word %d T0 " TDX " T1 " TDX "\n",
2834
                __func__, word, T0, T1);
2888
        fprintf(logfile, "%s word %d entry " TDX " value " TDX "\n",
2889
                __func__, word, entry, value);
2835 2890
    }
2836 2891
#endif
2837 2892
    do_flush_tlbs = 0;
2838
    T0 &= 0x3F;
2839
    tlb = &env->tlb[T0].tlbe;
2893
    entry &= 0x3F;
2894
    tlb = &env->tlb[entry].tlbe;
2840 2895
    switch (word) {
2841 2896
    default:
2842 2897
        /* Just here to please gcc */
2843 2898
    case 0:
2844
        EPN = T1 & 0xFFFFFC00;
2899
        EPN = value & 0xFFFFFC00;
2845 2900
        if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN)
2846 2901
            do_flush_tlbs = 1;
2847 2902
        tlb->EPN = EPN;
2848
        size = booke_tlb_to_page_size((T1 >> 4) & 0xF);
2903
        size = booke_tlb_to_page_size((value >> 4) & 0xF);
2849 2904
        if ((tlb->prot & PAGE_VALID) && tlb->size < size)
2850 2905
            do_flush_tlbs = 1;
2851 2906
        tlb->size = size;
2852 2907
        tlb->attr &= ~0x1;
2853
        tlb->attr |= (T1 >> 8) & 1;
2854
        if (T1 & 0x200) {
2908
        tlb->attr |= (value >> 8) & 1;
2909
        if (value & 0x200) {
2855 2910
            tlb->prot |= PAGE_VALID;
2856 2911
        } else {
2857 2912
            if (tlb->prot & PAGE_VALID) {
......
2864 2919
            tlb_flush(env, 1);
2865 2920
        break;
2866 2921
    case 1:
2867
        RPN = T1 & 0xFFFFFC0F;
2922
        RPN = value & 0xFFFFFC0F;
2868 2923
        if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN)
2869 2924
            tlb_flush(env, 1);
2870 2925
        tlb->RPN = RPN;
2871 2926
        break;
2872 2927
    case 2:
2873
        tlb->attr = (tlb->attr & 0x1) | (T1 & 0x0000FF00);
2928
        tlb->attr = (tlb->attr & 0x1) | (value & 0x0000FF00);
2874 2929
        tlb->prot = tlb->prot & PAGE_VALID;
2875
        if (T1 & 0x1)
2930
        if (value & 0x1)
2876 2931
            tlb->prot |= PAGE_READ << 4;
2877
        if (T1 & 0x2)
2932
        if (value & 0x2)
2878 2933
            tlb->prot |= PAGE_WRITE << 4;
2879
        if (T1 & 0x4)
2934
        if (value & 0x4)
2880 2935
            tlb->prot |= PAGE_EXEC << 4;
2881
        if (T1 & 0x8)
2936
        if (value & 0x8)
2882 2937
            tlb->prot |= PAGE_READ;
2883
        if (T1 & 0x10)
2938
        if (value & 0x10)
2884 2939
            tlb->prot |= PAGE_WRITE;
2885
        if (T1 & 0x20)
2940
        if (value & 0x20)
2886 2941
            tlb->prot |= PAGE_EXEC;
2887 2942
        break;
2888 2943
    }
2889 2944
}
2890 2945

  
2891
void do_440_tlbre (int word)
2946
target_ulong helper_440_tlbre (uint32_t word, target_ulong entry)
2892 2947
{
2893 2948
    ppcemb_tlb_t *tlb;
2949
    target_ulong ret;
2894 2950
    int size;
2895 2951

  
2896
    T0 &= 0x3F;
2897
    tlb = &env->tlb[T0].tlbe;
2952
    entry &= 0x3F;
2953
    tlb = &env->tlb[entry].tlbe;
2898 2954
    switch (word) {
2899 2955
    default:
2900 2956
        /* Just here to please gcc */
2901 2957
    case 0:
2902
        T0 = tlb->EPN;
2958
        ret = tlb->EPN;
2903 2959
        size = booke_page_size_to_tlb(tlb->size);
2904 2960
        if (size < 0 || size > 0xF)
2905 2961
            size = 1;
2906
        T0 |= size << 4;
2962
        ret |= size << 4;
2907 2963
        if (tlb->attr & 0x1)
2908
            T0 |= 0x100;
2964
            ret |= 0x100;
2909 2965
        if (tlb->prot & PAGE_VALID)
2910
            T0 |= 0x200;
2966
            ret |= 0x200;
2911 2967
        env->spr[SPR_440_MMUCR] &= ~0x000000FF;
2912 2968
        env->spr[SPR_440_MMUCR] |= tlb->PID;
2913 2969
        break;
2914 2970
    case 1:
2915
        T0 = tlb->RPN;
2971
        ret = tlb->RPN;
2916 2972
        break;
2917 2973
    case 2:
2918
        T0 = tlb->attr & ~0x1;
2974
        ret = tlb->attr & ~0x1;
2919 2975
        if (tlb->prot & (PAGE_READ << 4))
2920
            T0 |= 0x1;
2976
            ret |= 0x1;
2921 2977
        if (tlb->prot & (PAGE_WRITE << 4))
2922
            T0 |= 0x2;
2978
            ret |= 0x2;
2923 2979
        if (tlb->prot & (PAGE_EXEC << 4))
2924
            T0 |= 0x4;
2980
            ret |= 0x4;
2925 2981
        if (tlb->prot & PAGE_READ)
2926
            T0 |= 0x8;
2982
            ret |= 0x8;
2927 2983
        if (tlb->prot & PAGE_WRITE)
2928
            T0 |= 0x10;
2984
            ret |= 0x10;
2929 2985
        if (tlb->prot & PAGE_EXEC)
2930
            T0 |= 0x20;
2986
            ret |= 0x20;
2931 2987
        break;
2932 2988
    }
2989
    return ret;
2933 2990
}
2991

  
2992
target_ulong helper_440_tlbsx (target_ulong address)
2993
{
2994
    return ppcemb_tlb_search(env, address, env->spr[SPR_440_MMUCR] & 0xFF);
2995
}
2996

  
2934 2997
#endif /* !CONFIG_USER_ONLY */
b/target-ppc/op_helper.h
34 34
void do_store_hid0_601 (void);
35 35
#endif
36 36

  
37
/* PowerPC 440 specific helpers */
38
#if !defined(CONFIG_USER_ONLY)
39
void do_440_tlbre (int word);
40
void do_440_tlbwe (int word);
41
#endif
42

  
43
/* PowerPC 4xx specific helpers */
44
#if !defined(CONFIG_USER_ONLY)
45
void do_4xx_tlbre_lo (void);
46
void do_4xx_tlbre_hi (void);
47
void do_4xx_tlbwe_lo (void);
48
void do_4xx_tlbwe_hi (void);
49
#endif
50

  
51 37
/* PowerPC 403 specific helpers */
52 38
#if !defined(CONFIG_USER_ONLY)
53 39
void do_load_403_pb (int num);
b/target-ppc/translate.c
4208 4208
#if defined(CONFIG_USER_ONLY)
4209 4209
    GEN_EXCP_PRIVREG(ctx);
4210 4210
#else
4211
    TCGv t0;
4211 4212
    if (unlikely(!ctx->supervisor)) {
4212 4213
        GEN_EXCP_PRIVREG(ctx);
4213 4214
        return;
4214 4215
    }
4215
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4216
    gen_op_load_sr();
4217
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4216
    t0 = tcg_const_tl(SR(ctx->opcode));
4217
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4218
    tcg_temp_free(t0);
4218 4219
#endif
4219 4220
}
4220 4221

  
......
4224 4225
#if defined(CONFIG_USER_ONLY)
4225 4226
    GEN_EXCP_PRIVREG(ctx);
4226 4227
#else
4228
    TCGv t0;
4227 4229
    if (unlikely(!ctx->supervisor)) {
4228 4230
        GEN_EXCP_PRIVREG(ctx);
4229 4231
        return;
4230 4232
    }
4231
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4232
    gen_op_srli_T1(28);
4233
    gen_op_load_sr();
4234
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4233
    t0 = tcg_temp_new();
4234
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4235
    tcg_gen_andi_tl(t0, t0, 0xF);
4236
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4237
    tcg_temp_free(t0);
4235 4238
#endif
4236 4239
}
4237 4240

  
......
4241 4244
#if defined(CONFIG_USER_ONLY)
4242 4245
    GEN_EXCP_PRIVREG(ctx);
4243 4246
#else
4247
    TCGv t0;
4244 4248
    if (unlikely(!ctx->supervisor)) {
4245 4249
        GEN_EXCP_PRIVREG(ctx);
4246 4250
        return;
4247 4251
    }
4248
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4249
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4250
    gen_op_store_sr();
4252
    t0 = tcg_const_tl(SR(ctx->opcode));
4253
    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4254
    tcg_temp_free(t0);
4251 4255
#endif
4252 4256
}
4253 4257

  
......
4257 4261
#if defined(CONFIG_USER_ONLY)
4258 4262
    GEN_EXCP_PRIVREG(ctx);
4259 4263
#else
4264
    TCGv t0;
4260 4265
    if (unlikely(!ctx->supervisor)) {
4261 4266
        GEN_EXCP_PRIVREG(ctx);
4262 4267
        return;
4263 4268
    }
4264
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4265
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4266
    gen_op_srli_T1(28);
4267
    gen_op_store_sr();
4269
    t0 = tcg_temp_new();
4270
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4271
    tcg_gen_andi_tl(t0, t0, 0xF);
4272
    gen_helper_store_sr(t0, cpu_gpr[rD(ctx->opcode)]);
4273
    tcg_temp_free(t0);
4268 4274
#endif
4269 4275
}
4270 4276

  
......
4276 4282
#if defined(CONFIG_USER_ONLY)
4277 4283
    GEN_EXCP_PRIVREG(ctx);
4278 4284
#else
4285
    TCGv t0;
4279 4286
    if (unlikely(!ctx->supervisor)) {
4280 4287
        GEN_EXCP_PRIVREG(ctx);
4281 4288
        return;
4282 4289
    }
4283
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4284
    gen_op_load_slb();
4285
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4290
    t0 = tcg_const_tl(SR(ctx->opcode));
4291
    gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
4292
    tcg_temp_free(t0);
4286 4293
#endif
4287 4294
}
4288 4295

  
......
4293 4300
#if defined(CONFIG_USER_ONLY)
4294 4301
    GEN_EXCP_PRIVREG(ctx);
4295 4302
#else
4303
    TCGv t0;
4296 4304
    if (unlikely(!ctx->supervisor)) {
4297 4305
        GEN_EXCP_PRIVREG(ctx);
4298 4306
        return;
4299 4307
    }
4300
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4301
    gen_op_srli_T1(28);
4302
    gen_op_load_slb();
4303
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4308
    t0 = tcg_temp_new();
4309
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4310
    tcg_gen_andi_tl(t0, t0, 0xF);
4311
    gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
4312
    tcg_temp_free(t0);
4304 4313
#endif
4305 4314
}
4306 4315

  
......
4310 4319
#if defined(CONFIG_USER_ONLY)
4311 4320
    GEN_EXCP_PRIVREG(ctx);
4312 4321
#else
4322
    TCGv t0;
4313 4323
    if (unlikely(!ctx->supervisor)) {
4314 4324
        GEN_EXCP_PRIVREG(ctx);
4315 4325
        return;
4316 4326
    }
4317
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4318
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4319
    gen_op_store_slb();
4327
    t0 = tcg_const_tl(SR(ctx->opcode));
4328
    gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
4329
    tcg_temp_free(t0);
4320 4330
#endif
4321 4331
}
4322 4332

  
......
4327 4337
#if defined(CONFIG_USER_ONLY)
4328 4338
    GEN_EXCP_PRIVREG(ctx);
4329 4339
#else
4340
    TCGv t0;
4330 4341
    if (unlikely(!ctx->supervisor)) {
4331 4342
        GEN_EXCP_PRIVREG(ctx);
4332 4343
        return;
4333 4344
    }
4334
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4335
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4336
    gen_op_srli_T1(28);
4337
    gen_op_store_slb();
4345
    t0 = tcg_temp_new();
4346
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4347
    tcg_gen_andi_tl(t0, t0, 0xF);
4348
    gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
4349
    tcg_temp_free(t0);
4338 4350
#endif
4339 4351
}
4340 4352
#endif /* defined(TARGET_PPC64) */
......
4351 4363
        GEN_EXCP_PRIVOPC(ctx);
4352 4364
        return;
4353 4365
    }
4354
    gen_op_tlbia();
4366
    gen_helper_tlbia();
4355 4367
#endif
4356 4368
}
4357 4369

  
......
4365 4377
        GEN_EXCP_PRIVOPC(ctx);
4366 4378
        return;
4367 4379
    }
4368
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4369 4380
#if defined(TARGET_PPC64)
4370
    if (ctx->sf_mode)
4371
        gen_op_tlbie_64();
4372
    else
4381
    if (!ctx->sf_mode) {
4382
        TCGv t0 = tcg_temp_new();
4383
        tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
4384
        gen_helper_tlbie(t0);
4385
        tcg_temp_free(t0);
4386
    } else
4373 4387
#endif
4374
        gen_op_tlbie();
4388
        gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
4375 4389
#endif
4376 4390
}
4377 4391

  
......
4403 4417
        GEN_EXCP_PRIVOPC(ctx);
4404 4418
        return;
4405 4419
    }
4406
    gen_op_slbia();
4420
    gen_helper_slbia();
4407 4421
#endif
4408 4422
}
4409 4423

  
......
4417 4431
        GEN_EXCP_PRIVOPC(ctx);
4418 4432
        return;
4419 4433
    }
4420
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4421
    gen_op_slbie();
4434
    gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]);
4422 4435
#endif
4423 4436
}
4424 4437
#endif
......
5129 5142
        GEN_EXCP_PRIVOPC(ctx);
5130 5143
        return;
5131 5144
    }
5132
    gen_helper_load_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5145
    gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5133 5146
#endif
5134 5147
}
5135 5148

  
......
5143 5156
        GEN_EXCP_PRIVOPC(ctx);
5144 5157
        return;
5145 5158
    }
5146
    gen_helper_load_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5159
    gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5147 5160
#endif
5148 5161
}
5149 5162

  
......
5158 5171
        GEN_EXCP_PRIVOPC(ctx);
5159 5172
        return;
5160 5173
    }
5161
    gen_helper_load_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5174
    gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5162 5175
#endif
5163 5176
}
5164 5177

  
......
5172 5185
        GEN_EXCP_PRIVOPC(ctx);
5173 5186
        return;
5174 5187
    }
5175
    gen_helper_load_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5188
    gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5176 5189
#endif
5177 5190
}
5178 5191

  
......
5208 5221
#if defined(CONFIG_USER_ONLY)
5209 5222
    GEN_EXCP_PRIVOPC(ctx);
5210 5223
#else
5224
    int ra = rA(ctx->opcode);
5225
    int rd = rD(ctx->opcode);
5226
    TCGv t0;
5211 5227
    if (unlikely(!ctx->supervisor)) {
5212 5228
        GEN_EXCP_PRIVOPC(ctx);
5213 5229
        return;
5214 5230
    }
5215
    int ra = rA(ctx->opcode);
5216
    int rd = rD(ctx->opcode);
5217

  
5218
    gen_addr_reg_index(cpu_T[0], ctx);
5219
    gen_op_POWER_mfsri();
5220
    tcg_gen_mov_tl(cpu_gpr[rd], cpu_T[0]);
5231
    t0 = tcg_temp_new();
5232
    gen_addr_reg_index(t0, ctx);
5233
    tcg_gen_shri_tl(t0, t0, 28);
5234
    tcg_gen_andi_tl(t0, t0, 0xF);
5235
    gen_helper_load_sr(cpu_gpr[rd], t0);
5236
    tcg_temp_free(t0);
5221 5237
    if (ra != 0 && ra != rd)
5222
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[1]);
5238
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5223 5239
#endif
5224 5240
}
5225 5241

  
......
5389 5405
#if defined(CONFIG_USER_ONLY)
5390 5406
    GEN_EXCP_PRIVOPC(ctx);
5391 5407
#else
5408
    TCGv t0;
5392 5409
    if (unlikely(!ctx->supervisor)) {
5393 5410
        GEN_EXCP_PRIVOPC(ctx);
5394 5411
        return;
5395 5412
    }
5396
    gen_addr_reg_index(cpu_T[0], ctx);
5397
    /* Use the same micro-ops as for tlbie */
5413
    gen_addr_reg_index(t0, ctx);
5398 5414
#if defined(TARGET_PPC64)
5399
    if (ctx->sf_mode)
5400
        gen_op_tlbie_64();
5401
    else
5415
    if (!ctx->sf_mode)
5416
        tcg_gen_ext32u_tl(t0, t0);
5402 5417
#endif
5403
        gen_op_tlbie();
5418
    gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
5419
    tcg_temp_free(t0);
5404 5420
#endif
5405 5421
}
5406 5422

  
......
5861 5877
    }
5862 5878
    switch (rB(ctx->opcode)) {
5863 5879
    case 0:
5864
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5865
        gen_op_4xx_tlbre_hi();
5866
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5880
        gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5867 5881
        break;
5868 5882
    case 1:
5869
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5870
        gen_op_4xx_tlbre_lo();
5871
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5883
        gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5872 5884
        break;
5873 5885
    default:
5874 5886
        GEN_EXCP_INVAL(ctx);
......
5883 5895
#if defined(CONFIG_USER_ONLY)
5884 5896
    GEN_EXCP_PRIVOPC(ctx);
5885 5897
#else
5898
    TCGv t0;
5886 5899
    if (unlikely(!ctx->supervisor)) {
5887 5900
        GEN_EXCP_PRIVOPC(ctx);
5888 5901
        return;
5889 5902
    }
5890
    gen_addr_reg_index(cpu_T[0], ctx);
5891
    gen_op_4xx_tlbsx();
5892
    if (Rc(ctx->opcode))
5893
        gen_op_4xx_tlbsx_check();
5894
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5903
    t0 = tcg_temp_new();
5904
    gen_addr_reg_index(t0, ctx);
5905
    gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5906
    tcg_temp_free(t0);
5907
    if (Rc(ctx->opcode)) {
5908
        int l1 = gen_new_label();
5909
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
5910
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
5911
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
5912
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5913
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5914
        gen_set_label(l1);
5915
    }
5895 5916
#endif
5896 5917
}
5897 5918

  
......
5907 5928
    }
5908 5929
    switch (rB(ctx->opcode)) {
5909 5930
    case 0:
5910
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5911
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5912
        gen_op_4xx_tlbwe_hi();
5931
        gen_helper_4xx_tlbwe_hi(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5913 5932
        break;
5914 5933
    case 1:
5915
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5916
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5917
        gen_op_4xx_tlbwe_lo();
5934
        gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5918 5935
        break;
5919 5936
    default:
5920 5937
        GEN_EXCP_INVAL(ctx);
......
5938 5955
    case 0:
5939 5956
    case 1:
5940 5957
    case 2:
5941
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5942
        gen_op_440_tlbre(rB(ctx->opcode));
5943
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5958
        {
5959
            TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
5960
            gen_helper_440_tlbwe(t0, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5961
            tcg_temp_free_i32(t0);
5962
        }
5944 5963
        break;
5945 5964
    default:
5946 5965
        GEN_EXCP_INVAL(ctx);
......
5955 5974
#if defined(CONFIG_USER_ONLY)
5956 5975
    GEN_EXCP_PRIVOPC(ctx);
5957 5976
#else
5977
    TCGv t0;
5958 5978
    if (unlikely(!ctx->supervisor)) {
5959 5979
        GEN_EXCP_PRIVOPC(ctx);
5960 5980
        return;
5961 5981
    }
5962
    gen_addr_reg_index(cpu_T[0], ctx);
5963
    gen_op_440_tlbsx();
5964
    if (Rc(ctx->opcode))
5965
        gen_op_4xx_tlbsx_check();
5966
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5982
    t0 = tcg_temp_new();
5983
    gen_addr_reg_index(t0, ctx);
5984
    gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5985
    tcg_temp_free(t0);
5986
    if (Rc(ctx->opcode)) {
5987
        int l1 = gen_new_label();
5988
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
5989
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
5990
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
5991
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5992
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5993
        gen_set_label(l1);
5994
    }
5967 5995
#endif
5968 5996
}
5969 5997

  
......
5981 6009
    case 0:
5982 6010
    case 1:
5983 6011
    case 2:
5984
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5985
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5986
        gen_op_440_tlbwe(rB(ctx->opcode));
6012
        {
6013
            TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6014
            gen_helper_440_tlbwe(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
6015
            tcg_temp_free_i32(t0);
6016
        }
5987 6017
        break;
5988 6018
    default:
5989 6019
        GEN_EXCP_INVAL(ctx);

Also available in: Unified diff