From 37e62398ab1deb5cbf425cca1d43c85f0fcb986c Mon Sep 17 00:00:00 2001 From: Harsh Prateek Bora Date: Thu, 10 Oct 2024 11:17:36 +0530 Subject: target/ppc: optimize p8 exception handling routines Most of the p8 exception handling accesses env->pending_interrupts and env->spr[SPR_LPCR] at multiple places. Passing it directly as local variables simplifies the code and avoids multiple indirect accesses. Reviewed-by: Nicholas Piggin Signed-off-by: Harsh Prateek Bora Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 60 ++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 7074e6c894..38733b7521 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1765,39 +1765,42 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env) PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | \ PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM) -static int p8_interrupt_powersave(CPUPPCState *env) +static int p8_interrupt_powersave(uint32_t pending_interrupts, + target_ulong lpcr) { - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { + if ((pending_interrupts & PPC_INTERRUPT_EXT) && + (lpcr & LPCR_P8_PECE2)) { return PPC_INTERRUPT_EXT; } - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { + if ((pending_interrupts & PPC_INTERRUPT_DECR) && + (lpcr & LPCR_P8_PECE3)) { return PPC_INTERRUPT_DECR; } - if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + if ((pending_interrupts & PPC_INTERRUPT_MCK) && + (lpcr & LPCR_P8_PECE4)) { return PPC_INTERRUPT_MCK; } - if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + if ((pending_interrupts & PPC_INTERRUPT_HMI) && + (lpcr & LPCR_P8_PECE4)) { return PPC_INTERRUPT_HMI; } - if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { + if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) && + (lpcr & LPCR_P8_PECE0)) { return PPC_INTERRUPT_DOORBELL; } - if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { + if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) && + (lpcr & LPCR_P8_PECE1)) { return PPC_INTERRUPT_HDOORBELL; } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + if (pending_interrupts & PPC_INTERRUPT_RESET) { return PPC_INTERRUPT_RESET; } return 0; } -static int p8_next_unmasked_interrupt(CPUPPCState *env) +static int p8_next_unmasked_interrupt(CPUPPCState *env, + uint32_t pending_interrupts, + target_ulong lpcr) { CPUState *cs = env_cpu(env); @@ -1808,18 +1811,18 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env) if (cs->halted) { /* LPCR[PECE] controls which interrupts can exit power-saving mode */ - return p8_interrupt_powersave(env); + return p8_interrupt_powersave(pending_interrupts, lpcr); } /* Machine check exception */ - if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + if (pending_interrupts & PPC_INTERRUPT_MCK) { return PPC_INTERRUPT_MCK; } /* Hypervisor decrementer exception */ - if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { + if (pending_interrupts & PPC_INTERRUPT_HDECR) { /* LPCR will be clear when not supported so this will work */ - bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); + bool hdice = !!(lpcr & LPCR_HDICE); if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) { /* HDEC clears on delivery */ return PPC_INTERRUPT_HDECR; @@ -1827,9 +1830,9 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env) } /* External interrupt can ignore MSR:EE under some circumstances */ - if (env->pending_interrupts & PPC_INTERRUPT_EXT) { - bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + if (pending_interrupts & PPC_INTERRUPT_EXT) { + bool lpes0 = !!(lpcr & LPCR_LPES0); + bool heic = !!(lpcr & LPCR_HEIC); /* HEIC blocks delivery to the hypervisor */ if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) && !FIELD_EX64(env->msr, MSR, PR))) || @@ -1839,20 +1842,20 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env) } if (msr_ee != 0) { /* Decrementer exception */ - if (env->pending_interrupts & PPC_INTERRUPT_DECR) { + if (pending_interrupts & PPC_INTERRUPT_DECR) { return PPC_INTERRUPT_DECR; } - if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { + if (pending_interrupts & PPC_INTERRUPT_DOORBELL) { return PPC_INTERRUPT_DOORBELL; } - if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { + if (pending_interrupts & PPC_INTERRUPT_HDOORBELL) { return PPC_INTERRUPT_HDOORBELL; } - if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { + if (pending_interrupts & PPC_INTERRUPT_PERFM) { return PPC_INTERRUPT_PERFM; } /* EBB exception */ - if (env->pending_interrupts & PPC_INTERRUPT_EBB) { + if (pending_interrupts & PPC_INTERRUPT_EBB) { /* * EBB exception must be taken in problem state and * with BESCR_GE set. @@ -2021,7 +2024,8 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env) case POWERPC_EXCP_POWER7: return p7_next_unmasked_interrupt(env); case POWERPC_EXCP_POWER8: - return p8_next_unmasked_interrupt(env); + return p8_next_unmasked_interrupt(env, env->pending_interrupts, + env->spr[SPR_LPCR]); case POWERPC_EXCP_POWER9: case POWERPC_EXCP_POWER10: case POWERPC_EXCP_POWER11: -- cgit v1.2.3