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); | ... | ... |