diff options
Diffstat (limited to 'target-ppc/op_helper.c')
-rw-r--r-- | target-ppc/op_helper.c | 112 |
1 files changed, 75 insertions, 37 deletions
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 55b5ca5653..c21a38aea4 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -881,12 +881,17 @@ void do_fcmpo (void) #if !defined (CONFIG_USER_ONLY) void do_rfi (void) { - env->nip = (target_ulong)(env->spr[SPR_SRR0] & ~0x00000003); - T0 = (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); #if defined(TARGET_PPC64) - ppc_store_msr_32(env, T0); + if (env->spr[SPR_SRR1] & (1ULL << MSR_SF)) { + env->nip = (uint64_t)(env->spr[SPR_SRR0] & ~0x00000003); + do_store_msr(env, (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL)); + } else { + env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003); + ppc_store_msr_32(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL)); + } #else - do_store_msr(env, T0); + env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003); + do_store_msr(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL)); #endif #if defined (DEBUG_OP) dump_rfi(); @@ -895,33 +900,15 @@ void do_rfi (void) } #if defined(TARGET_PPC64) -void do_rfi_32 (void) -{ - env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003); - T0 = (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); - ppc_store_msr_32(env, T0); -#if defined (DEBUG_OP) - dump_rfi(); -#endif - env->interrupt_request |= CPU_INTERRUPT_EXITTB; -} - void do_rfid (void) { - env->nip = (target_ulong)(env->spr[SPR_SRR0] & ~0x00000003); - T0 = (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); - do_store_msr(env, T0); -#if defined (DEBUG_OP) - dump_rfi(); -#endif - env->interrupt_request |= CPU_INTERRUPT_EXITTB; -} - -void do_rfid_32 (void) -{ - env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003); - T0 = (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); - do_store_msr(env, T0); + if (env->spr[SPR_SRR1] & (1ULL << MSR_SF)) { + env->nip = (uint64_t)(env->spr[SPR_SRR0] & ~0x00000003); + do_store_msr(env, (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL)); + } else { + env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003); + do_store_msr(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL)); + } #if defined (DEBUG_OP) dump_rfi(); #endif @@ -936,8 +923,9 @@ void do_tw (int flags) ((int32_t)T0 > (int32_t)T1 && (flags & 0x08)) || ((int32_t)T0 == (int32_t)T1 && (flags & 0x04)) || ((uint32_t)T0 < (uint32_t)T1 && (flags & 0x02)) || - ((uint32_t)T0 > (uint32_t)T1 && (flags & 0x01))))) + ((uint32_t)T0 > (uint32_t)T1 && (flags & 0x01))))) { do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP); + } } #if defined(TARGET_PPC64) @@ -1196,34 +1184,84 @@ void do_405_check_sat (void) } #if !defined(CONFIG_USER_ONLY) -void do_4xx_rfci (void) +void do_40x_rfci (void) { env->nip = env->spr[SPR_40x_SRR2]; - T0 = env->spr[SPR_40x_SRR3] & ~0xFFFF0000; - do_store_msr(env, T0); + do_store_msr(env, env->spr[SPR_40x_SRR3] & ~0xFFFF0000); +#if defined (DEBUG_OP) + dump_rfi(); +#endif + env->interrupt_request = CPU_INTERRUPT_EXITTB; +} + +void do_rfci (void) +{ +#if defined(TARGET_PPC64) + if (env->spr[SPR_BOOKE_CSRR1] & (1 << MSR_CM)) { + env->nip = (uint64_t)env->spr[SPR_BOOKE_CSRR0]; + } else +#endif + { + env->nip = (uint32_t)env->spr[SPR_BOOKE_CSRR0]; + } + do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_CSRR1] & ~0x3FFF0000); +#if defined (DEBUG_OP) + dump_rfi(); +#endif + env->interrupt_request = CPU_INTERRUPT_EXITTB; +} + +void do_rfdi (void) +{ +#if defined(TARGET_PPC64) + if (env->spr[SPR_BOOKE_DSRR1] & (1 << MSR_CM)) { + env->nip = (uint64_t)env->spr[SPR_BOOKE_DSRR0]; + } else +#endif + { + env->nip = (uint32_t)env->spr[SPR_BOOKE_DSRR0]; + } + do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_DSRR1] & ~0x3FFF0000); +#if defined (DEBUG_OP) + dump_rfi(); +#endif + env->interrupt_request = CPU_INTERRUPT_EXITTB; +} + +void do_rfmci (void) +{ +#if defined(TARGET_PPC64) + if (env->spr[SPR_BOOKE_MCSRR1] & (1 << MSR_CM)) { + env->nip = (uint64_t)env->spr[SPR_BOOKE_MCSRR0]; + } else +#endif + { + env->nip = (uint32_t)env->spr[SPR_BOOKE_MCSRR0]; + } + do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_MCSRR1] & ~0x3FFF0000); #if defined (DEBUG_OP) dump_rfi(); #endif env->interrupt_request = CPU_INTERRUPT_EXITTB; } -void do_4xx_load_dcr (int dcrn) +void do_load_dcr (void) { target_ulong val; if (unlikely(env->dcr_read == NULL)) do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL); - else if (unlikely((*env->dcr_read)(env->dcr_env, dcrn, &val) != 0)) + else if (unlikely((*env->dcr_read)(env->dcr_env, T0, &val) != 0)) do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG); else T0 = val; } -void do_4xx_store_dcr (int dcrn) +void do_store_dcr (void) { if (unlikely(env->dcr_write == NULL)) do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL); - else if (unlikely((*env->dcr_write)(env->dcr_env, dcrn, T0) != 0)) + else if (unlikely((*env->dcr_write)(env->dcr_env, T0, T1) != 0)) do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG); } |