Commit 74d37793f4ea5f30ed6c0af6c449a204dacd8b44
1 parent
331dadde
target-ppc: convert SLB/TLB instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5895 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
7 changed files
with
272 additions
and
332 deletions
target-ppc/cpu.h
target-ppc/helper.c
... | ... | @@ -2110,13 +2110,6 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value) |
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) | ... | ... |
target-ppc/helper.h
... | ... | @@ -163,10 +163,28 @@ DEF_HELPER_2(efdcmpgt, i32, i64, i64) |
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 | ... | ... |
target-ppc/op.c
... | ... | @@ -27,33 +27,6 @@ |
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,13 +191,6 @@ void OPPROTO op_store_dbatl (void) |
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,50 +209,6 @@ void OPPROTO op_store_excp_vector (void) |
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,78 +260,6 @@ void OPPROTO op_store_601_batu (void) |
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) | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -2552,9 +2552,55 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) |
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,18 +2626,18 @@ static void helper_load_6xx_tlb (target_ulong new_EPN, int is_code) |
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,14 +2658,14 @@ static void helper_load_74xx_tlb (target_ulong new_EPN, int is_code) |
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,81 +2737,85 @@ static always_inline int booke_page_size_to_tlb (target_ulong page_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,28 +2841,28 @@ void do_4xx_tlbwe_hi (void) |
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,8 +2871,13 @@ void do_4xx_tlbwe_lo (void) |
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,28 +2885,28 @@ void do_440_tlbwe (int word) |
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,71 +2919,79 @@ void do_440_tlbwe (int word) |
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 */ | ... | ... |
target-ppc/op_helper.h
... | ... | @@ -34,20 +34,6 @@ void do_POWER_rac (void); |
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); | ... | ... |
target-ppc/translate.c
... | ... | @@ -4208,13 +4208,14 @@ GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT) |
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,14 +4225,16 @@ GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT) |
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,13 +4244,14 @@ GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT) |
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,14 +4261,16 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) |
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,13 +4282,14 @@ GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B) |
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,14 +4300,16 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001, |
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,13 +4319,14 @@ GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B) |
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,14 +4337,16 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, |
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,7 +4363,7 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA) |
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,13 +4377,15 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE) |
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,7 +4417,7 @@ GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI) |
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,8 +4431,7 @@ GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI) |
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,7 +5142,7 @@ GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB) |
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,7 +5156,7 @@ GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB) |
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,7 +5171,7 @@ GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB) |
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,7 +5185,7 @@ GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB) |
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,18 +5221,21 @@ GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER) |
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,18 +5405,18 @@ GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA) |
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,14 +5877,10 @@ GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB) |
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,15 +5895,24 @@ GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB) |
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,14 +5928,10 @@ GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB) |
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,9 +5955,11 @@ GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) |
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,15 +5974,24 @@ GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE) |
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,9 +6009,11 @@ GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE) |
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); | ... | ... |