On Wed, 2025-09-24 at 09:52 -0500, Miles Glenn wrote:
> On Wed, 2025-09-24 at 18:02 +0530, Chinmay Rath wrote:
> > On 9/18/25 23:57, Glenn Miles wrote:
> > > Adds the IBM PPE42 family of 32-bit processors supporting
> > > the PPE42, PPE42X and PPE42XM processor versions.  These
> > > processors are used as embedded processors in the IBM
> > > Power9, Power10 and Power12 processors for various
> > > tasks.  It is basically a stripped down version of the
> > > IBM PowerPC 405 processor, with some added instructions
> > > for handling 64-bit loads and stores.
> > > 
> > > For more information on the PPE 42 processor please visit:
> > > 
> > > https://wiki.raptorcs.com/w/images/a/a3/PPE_42X_Core_Users_Manual.pdf
> > > 
> > > Supports PPE42 SPR's (Including the MSR).
> > > 
> > > Does not yet support exceptions, new PPE42 instructions and
> > > does not prevent access to some invalid instructions and
> > > registers (currently allows access to invalid GPR's and CR
> > > fields).
> > > 
> > > Signed-off-by: Glenn Miles <mil...@linux.ibm.com>
> > > ---
> > >   target/ppc/cpu-models.c  |   7 ++
> > >   target/ppc/cpu_init.c    | 204 ++++++++++++++++++++++++++++++++-------
> > >   target/ppc/helper_regs.c |  41 +++++---
> > >   target/ppc/translate.c   |   6 +-
> > >   4 files changed, 203 insertions(+), 55 deletions(-)
> > > 
> > > diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
> > > index ea86ea202a..09f73e23a8 100644
> > > --- a/target/ppc/cpu-models.c
> > > +++ b/target/ppc/cpu-models.c
> > > @@ -116,6 +116,13 @@
> > >                   NULL)
> > >       POWERPC_DEF("x2vp20",        CPU_POWERPC_X2VP20,                 
> > > 405,
> > >                   NULL)
> > > +    /* PPE42 Embedded Controllers                                        
> > >     */
> > > +    POWERPC_DEF("PPE42",         CPU_POWERPC_PPE42,                  
> > > ppe42,
> > > +                "Generic PPE 42")
> > > +    POWERPC_DEF("PPE42X",        CPU_POWERPC_PPE42X,                 
> > > ppe42x,
> > > +                "Generic PPE 42X")
> > > +    POWERPC_DEF("PPE42XM",       CPU_POWERPC_PPE42XM,                
> > > ppe42xm,
> > > +                "Generic PPE 42XM")
> > >       /* PowerPC 440 family                                               
> > >      */
> > >   #if defined(TODO_USER_ONLY)
> > >       POWERPC_DEF("440",           CPU_POWERPC_440,                    
> > > 440GP,
> > > diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> > > index db841f1260..b42673c6b5 100644
> > > --- a/target/ppc/cpu_init.c
> > > +++ b/target/ppc/cpu_init.c
> > > @@ -1653,6 +1653,47 @@ static void register_8xx_sprs(CPUPPCState *env)
> > >    * ... and more (thermal management, performance counters, ...)
> > >    */
> > >   
> > > +static void register_ppe42_sprs(CPUPPCState *env)
> > > +{
> > > +    spr_register(env, SPR_PPE42_EDR, "EDR",
> > > +                 SPR_NOACCESS, SPR_NOACCESS,
> > > +                 &spr_read_generic, &spr_write_generic,
> > > +                 0x00000000);
> > > +    spr_register(env, SPR_PPE42_ISR, "ISR",
> > > +                 SPR_NOACCESS, SPR_NOACCESS,
> > > +                 &spr_read_generic, &spr_write_generic,
> > > +                 0x00000000);
> > > +    spr_register(env, SPR_PPE42_IVPR, "IVPR",
> > > +                 SPR_NOACCESS, SPR_NOACCESS,
> > > +                 &spr_read_generic, SPR_NOACCESS,
> > > +                 0xfff80000);
> > > +    spr_register(env, SPR_PPE42_PIR, "PIR",
> > > +                 SPR_NOACCESS, SPR_NOACCESS,
> > > +                 &spr_read_generic, &spr_write_pir,
> > > +                 0x00000000);
> > > +    spr_register(env, SPR_PPE42_DBCR, "DBCR",
> > > +                 SPR_NOACCESS, SPR_NOACCESS,
> > > +                 &spr_read_generic, &spr_write_40x_dbcr0,
> > > +                 0x00000000);
> > > +    spr_register(env, SPR_PPE42_DACR, "DACR",
> > > +                 SPR_NOACCESS, SPR_NOACCESS,
> > > +                 &spr_read_generic, &spr_write_generic,
> > > +                 0x00000000);
> > > +    /* Timer */
> > > +    spr_register(env, SPR_DECR, "DECR",
> > > +                 SPR_NOACCESS, SPR_NOACCESS,
> > > +                 &spr_read_decr, &spr_write_decr,
> > > +                 0x00000000);
> > > +    spr_register(env, SPR_PPE42_TSR, "TSR",
> > > +                 SPR_NOACCESS, SPR_NOACCESS,
> > > +                 &spr_read_generic, &spr_write_booke_tsr,
> > > +                 0x00000000);
> > > +    spr_register(env, SPR_BOOKE_TCR, "TCR",
> > > +                 SPR_NOACCESS, SPR_NOACCESS,
> > > +                 &spr_read_generic, &spr_write_booke_tcr,
> > > +                 0x00000000);
> > > +}
> > > +
> > >   
> > > /*****************************************************************************/
> > >   /* Exception vectors models                                             
> > >      */
> > >   static void init_excp_4xx(CPUPPCState *env)
> > > @@ -2200,6 +2241,79 @@ POWERPC_FAMILY(405)(ObjectClass *oc, const void 
> > > *data)
> > >                    POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
> > >   }
> > >   
> > > +static void init_proc_ppe42(CPUPPCState *env)
> > > +{
> > > +    register_ppe42_sprs(env);
> > > +
> > > +    env->dcache_line_size = 32;
> > > +    env->icache_line_size = 32;
> > > +    /* Allocate hardware IRQ controller */
> > > +    ppc40x_irq_init(env_archcpu(env));
> > > +
> > > +    SET_FIT_PERIOD(8, 12, 16, 20);
> > > +    SET_WDT_PERIOD(16, 20, 24, 28);
> > > +}
> > > +
> > > +static void ppe42_class_common_init(PowerPCCPUClass *pcc)
> > > +{
> > > +    pcc->init_proc = init_proc_ppe42;
> > > +    pcc->check_pow = check_pow_nocheck;
> > > +    pcc->check_attn = check_attn_none;
> > > +    pcc->insns_flags = PPC_INSNS_BASE |
> > > +                       PPC_WRTEE |
> > > +                       PPC_CACHE |
> > > +                       PPC_CACHE_DCBZ |
> > > +                       PPC_MEM_SYNC;
> > > +    pcc->msr_mask = R_MSR_SEM_MASK |
> > > +                    (1ull << MSR_IS0) |
> > > +                    R_MSR_SIBRC_MASK |
> > > +                    (1ull << MSR_LP) |
> > > +                    (1ull << MSR_WE) |
> > > +                    (1ull << MSR_IS1) |
> > > +                    (1ull << MSR_UIE) |
> > > +                    (1ull << MSR_EE) |
> > > +                    (1ull << MSR_ME) |
> > > +                    (1ull << MSR_IS2) |
> > > +                    (1ull << MSR_IS3) |
> > > +                    (1ull << MSR_IPE) |
> > > +                    R_MSR_SIBRCA_MASK;
> > > +    pcc->mmu_model = POWERPC_MMU_REAL;
> > > +    pcc->excp_model = POWERPC_EXCP_40x;
> > > +    pcc->bus_model = PPC_FLAGS_INPUT_PPE42;
> > > +    pcc->bfd_mach = bfd_mach_ppc_403;
> > > +    pcc->flags = POWERPC_FLAG_PPE42 | POWERPC_FLAG_BUS_CLK;
> > > +}
> > > +
> > > +POWERPC_FAMILY(ppe42)(ObjectClass *oc, const void *data)
> > > +{
> > > +    DeviceClass *dc = DEVICE_CLASS(oc);
> > > +    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> > > +
> > > +    dc->desc = "PPE 42";
> > > +    pcc->insns_flags2 = PPC2_PPE42;
> > > +    ppe42_class_common_init(pcc);
> > > +}
> > > +
> > > +POWERPC_FAMILY(ppe42x)(ObjectClass *oc, const void *data)
> > > +{
> > > +    DeviceClass *dc = DEVICE_CLASS(oc);
> > > +    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> > > +
> > > +    dc->desc = "PPE 42X";
> > > +    pcc->insns_flags2 = PPC2_PPE42 | PPC2_PPE42X;
> > > +    ppe42_class_common_init(pcc);
> > > +}
> > > +
> > > +POWERPC_FAMILY(ppe42xm)(ObjectClass *oc, const void *data)
> > > +{
> > > +    DeviceClass *dc = DEVICE_CLASS(oc);
> > > +    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> > > +
> > > +    dc->desc = "PPE 42XM";
> > > +    pcc->insns_flags2 = PPC2_PPE42 | PPC2_PPE42X | PPC2_PPE42XM;
> > > +    ppe42_class_common_init(pcc);
> > > +}
> > > +
> > >   static void init_proc_440EP(CPUPPCState *env)
> > >   {
> > >       register_BookE_sprs(env, 0x000000000000FFFFULL);
> > > @@ -6802,53 +6916,63 @@ static void init_ppc_proc(PowerPCCPU *cpu)
> > >   
> > >       /* MSR bits & flags consistency checks */
> > >       if (env->msr_mask & (1 << 25)) {
> > > -        switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
> > > +        switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE |
> > > +                              POWERPC_FLAG_PPE42)) {
> > >           case POWERPC_FLAG_SPE:
> > >           case POWERPC_FLAG_VRE:
> > > +        case POWERPC_FLAG_PPE42:
> > >               break;
> > >           default:
> > >               fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> > > -                    "Should define POWERPC_FLAG_SPE or 
> > > POWERPC_FLAG_VRE\n");
> > > +                    "Should define POWERPC_FLAG_SPE or 
> > > POWERPC_FLAG_VRE\n"
> > > +                    "or POWERPC_FLAG_PPE42\n");
> > >               exit(1);
> > >           }
> > >       } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
> > 
> > Hey Glenn,
> > 
> > Did you miss adding the POWERPC_FLAG_PPE42 flag here  ^  ?
> > 
> > Thanks,
> > Chinmay
> 
> No. All PPE42 processors will have bit 1 << 25 set in env->msr_mask, so
> it will always fall into the previous condition block and never enter
> the 2nd check.
> 
> Glenn
> 

Ah, sorry, I should have looked closer!  This is supposed to be
checking that if 1 << 25 is not set that we shouldn't be setting the
PPE42 flag either.  So, yes, I'll add that in v6.

Thanks,

Glenn

> > >           fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> > > -                "Should not define POWERPC_FLAG_SPE nor 
> > > POWERPC_FLAG_VRE\n");
> > > +                "Should not define POWERPC_FLAG_SPE nor 
> > > POWERPC_FLAG_VRE\n"
> > > +                "nor POWERPC_FLAG_PPE42\n");
> > >           exit(1);
> > >       }
> > >       if (env->msr_mask & (1 << 17)) {
> > > -        switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
> > > +        switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE |
> > > +                              POWERPC_FLAG_PPE42)) {
> > >           case POWERPC_FLAG_TGPR:
> > >           case POWERPC_FLAG_CE:
> > > +        case POWERPC_FLAG_PPE42:
> > >               break;
> > >           default:
> > >               fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> > > -                    "Should define POWERPC_FLAG_TGPR or 
> > > POWERPC_FLAG_CE\n");
> > > +                    "Should define POWERPC_FLAG_TGPR or 
> > > POWERPC_FLAG_CE\n"
> > > +                    "or POWERPC_FLAG_PPE42\n");
> > >               exit(1);
> > >           }
> > > -    } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
> > > +    } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE |
> > > +                             POWERPC_FLAG_PPE42)) {
> > >           fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> > > -                "Should not define POWERPC_FLAG_TGPR nor 
> > > POWERPC_FLAG_CE\n");
> > > +                "Should not define POWERPC_FLAG_TGPR nor 
> > > POWERPC_FLAG_CE\n"
> > > +                "nor POWERPC_FLAG_PPE42\n");
> > >           exit(1);
> > >       }
> > >       if (env->msr_mask & (1 << 10)) {
> > >           switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
> > > -                              POWERPC_FLAG_UBLE)) {
> > > +                              POWERPC_FLAG_UBLE | POWERPC_FLAG_PPE42)) {
> > >           case POWERPC_FLAG_SE:
> > >           case POWERPC_FLAG_DWE:
> > >           case POWERPC_FLAG_UBLE:
> > > +        case POWERPC_FLAG_PPE42:
> > >               break;
> > >           default:
> > >               fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> > >                       "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE 
> > > or "
> > > -                    "POWERPC_FLAG_UBLE\n");
> > > +                    "POWERPC_FLAG_UBLE or POWERPC_FLAG_PPE42\n");
> > >               exit(1);
> > >           }
> > >       } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
> > > -                             POWERPC_FLAG_UBLE)) {
> > > +                             POWERPC_FLAG_UBLE | POWERPC_FLAG_PPE42)) {
> > >           fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> > >                   "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE 
> > > nor "
> > > -                "POWERPC_FLAG_UBLE\n");
> > > +                "POWERPC_FLAG_UBLE nor POWERPC_FLAG_PPE42\n");
> > >               exit(1);
> > >       }
> > >       if (env->msr_mask & (1 << 9)) {
> > > @@ -6867,18 +6991,23 @@ static void init_ppc_proc(PowerPCCPU *cpu)
> > >           exit(1);
> > >       }
> > >       if (env->msr_mask & (1 << 2)) {
> > > -        switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
> > > +        switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM |
> > > +                              POWERPC_FLAG_PPE42)) {
> > >           case POWERPC_FLAG_PX:
> > >           case POWERPC_FLAG_PMM:
> > > +        case POWERPC_FLAG_PPE42:
> > >               break;
> > >           default:
> > >               fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> > > -                    "Should define POWERPC_FLAG_PX or 
> > > POWERPC_FLAG_PMM\n");
> > > +                    "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n"
> > > +                    "or POWERPC_FLAG_PPE42\n");
> > >               exit(1);
> > >           }
> > > -    } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
> > > +    } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM |
> > > +                             POWERPC_FLAG_PPE42)) {
> > >           fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> > > -                "Should not define POWERPC_FLAG_PX nor 
> > > POWERPC_FLAG_PMM\n");
> > > +                "Should not define POWERPC_FLAG_PX nor 
> > > POWERPC_FLAG_PMM\n"
> > > +                "nor POWERPC_FLAG_PPE42\n");
> > >           exit(1);
> > >       }
> > >       if ((env->flags & POWERPC_FLAG_BUS_CLK) == 0) {
> > > @@ -7243,39 +7372,40 @@ static void ppc_cpu_reset_hold(Object *obj, 
> > > ResetType type)
> > >       }
> > >   
> > >       msr = (target_ulong)0;
> > > -    msr |= (target_ulong)MSR_HVB;
> > > -    msr |= (target_ulong)1 << MSR_EP;
> > > +    if (!(env->flags & POWERPC_FLAG_PPE42)) {
> > > +        msr |= (target_ulong)MSR_HVB;
> > > +        msr |= (target_ulong)1 << MSR_EP;
> > >   #if defined(DO_SINGLE_STEP) && 0
> > > -    /* Single step trace mode */
> > > -    msr |= (target_ulong)1 << MSR_SE;
> > > -    msr |= (target_ulong)1 << MSR_BE;
> > > +        /* Single step trace mode */
> > > +        msr |= (target_ulong)1 << MSR_SE;
> > > +        msr |= (target_ulong)1 << MSR_BE;
> > >   #endif
> > >   #if defined(CONFIG_USER_ONLY)
> > > -    msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
> > > -    msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point 
> > > exceptions */
> > > -    msr |= (target_ulong)1 << MSR_FE1;
> > > -    msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
> > > -    msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
> > > -    msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
> > > -    msr |= (target_ulong)1 << MSR_PR;
> > > +        msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage 
> > > */
> > > +        msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point 
> > > exceptions */
> > > +        msr |= (target_ulong)1 << MSR_FE1;
> > > +        msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
> > > +        msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
> > > +        msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
> > > +        msr |= (target_ulong)1 << MSR_PR;
> > >   #if defined(TARGET_PPC64)
> > > -    msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
> > > +        msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
> > >   #endif
> > >   #if !TARGET_BIG_ENDIAN
> > > -    msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
> > > -    if (!((env->msr_mask >> MSR_LE) & 1)) {
> > > -        fprintf(stderr, "Selected CPU does not support 
> > > little-endian.\n");
> > > -        exit(1);
> > > -    }
> > > +        msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
> > > +        if (!((env->msr_mask >> MSR_LE) & 1)) {
> > > +            fprintf(stderr, "Selected CPU does not support 
> > > little-endian.\n");
> > > +            exit(1);
> > > +        }
> > >   #endif
> > >   #endif
> > >   
> > >   #if defined(TARGET_PPC64)
> > > -    if (mmu_is_64bit(env->mmu_model)) {
> > > -        msr |= (1ULL << MSR_SF);
> > > -    }
> > > +        if (mmu_is_64bit(env->mmu_model)) {
> > > +            msr |= (1ULL << MSR_SF);
> > > +        }
> > >   #endif
> > > -
> > > +    }
> > >       hreg_store_msr(env, msr, 1);
> > >   
> > >   #if !defined(CONFIG_USER_ONLY)
> > > diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
> > > index 5f21739749..41b7b939ec 100644
> > > --- a/target/ppc/helper_regs.c
> > > +++ b/target/ppc/helper_regs.c
> > > @@ -308,9 +308,6 @@ int hreg_store_msr(CPUPPCState *env, target_ulong 
> > > value, int alter_hv)
> > >           value &= ~(1 << MSR_ME);
> > >           value |= env->msr & (1 << MSR_ME);
> > >       }
> > > -    if ((value ^ env->msr) & (R_MSR_IR_MASK | R_MSR_DR_MASK)) {
> > > -        cpu_interrupt_exittb(cs);
> > > -    }
> > >       if ((env->mmu_model == POWERPC_MMU_BOOKE ||
> > >            env->mmu_model == POWERPC_MMU_BOOKE206) &&
> > >           ((value ^ env->msr) & R_MSR_GS_MASK)) {
> > > @@ -321,8 +318,14 @@ int hreg_store_msr(CPUPPCState *env, target_ulong 
> > > value, int alter_hv)
> > >           /* Swap temporary saved registers with GPRs */
> > >           hreg_swap_gpr_tgpr(env);
> > >       }
> > > -    if (unlikely((value ^ env->msr) & R_MSR_EP_MASK)) {
> > > -        env->excp_prefix = FIELD_EX64(value, MSR, EP) * 0xFFF00000;
> > > +    /* PPE42 uses IR, DR and EP MSR bits for other purposes */
> > > +    if (likely(!(env->flags & POWERPC_FLAG_PPE42))) {
> > > +        if ((value ^ env->msr) & (R_MSR_IR_MASK | R_MSR_DR_MASK)) {
> > > +            cpu_interrupt_exittb(cs);
> > > +        }
> > > +        if (unlikely((value ^ env->msr) & R_MSR_EP_MASK)) {
> > > +            env->excp_prefix = FIELD_EX64(value, MSR, EP) * 0xFFF00000;
> > > +        }
> > >       }
> > >       /*
> > >        * If PR=1 then EE, IR and DR must be 1
> > > @@ -464,6 +467,23 @@ void register_generic_sprs(PowerPCCPU *cpu)
> > >                    SPR_NOACCESS, SPR_NOACCESS,
> > >                    &spr_read_generic, &spr_write_generic,
> > >                    0x00000000);
> > > +
> > > +    spr_register(env, SPR_PVR, "PVR",
> > > +                 /* Linux permits userspace to read PVR */
> > > +#if defined(CONFIG_LINUX_USER)
> > > +                 &spr_read_generic,
> > > +#else
> > > +                 SPR_NOACCESS,
> > > +#endif
> > > +                 SPR_NOACCESS,
> > > +                 &spr_read_generic, SPR_NOACCESS,
> > > +                 pcc->pvr);
> > > +
> > > +    /* PPE42 doesn't support SPRG1-3, SVR or TB regs */
> > > +    if (env->insns_flags2 & PPC2_PPE42) {
> > > +        return;
> > > +    }
> > > +
> > >       spr_register(env, SPR_SPRG1, "SPRG1",
> > >                    SPR_NOACCESS, SPR_NOACCESS,
> > >                    &spr_read_generic, &spr_write_generic,
> > > @@ -477,17 +497,6 @@ void register_generic_sprs(PowerPCCPU *cpu)
> > >                    &spr_read_generic, &spr_write_generic,
> > >                    0x00000000);
> > >   
> > > -    spr_register(env, SPR_PVR, "PVR",
> > > -                 /* Linux permits userspace to read PVR */
> > > -#if defined(CONFIG_LINUX_USER)
> > > -                 &spr_read_generic,
> > > -#else
> > > -                 SPR_NOACCESS,
> > > -#endif
> > > -                 SPR_NOACCESS,
> > > -                 &spr_read_generic, SPR_NOACCESS,
> > > -                 pcc->pvr);
> > > -
> > >       /* Register SVR if it's defined to anything else than 
> > > POWERPC_SVR_NONE */
> > >       if (pcc->svr != POWERPC_SVR_NONE) {
> > >           if (pcc->svr & POWERPC_SVR_E500) {
> > > diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> > > index 27f90c3cc5..fc817dab54 100644
> > > --- a/target/ppc/translate.c
> > > +++ b/target/ppc/translate.c
> > > @@ -4264,8 +4264,10 @@ static void gen_mtmsr(DisasContext *ctx)
> > >           /* L=1 form only updates EE and RI */
> > >           mask &= (1ULL << MSR_RI) | (1ULL << MSR_EE);
> > >       } else {
> > > -        /* mtmsr does not alter S, ME, or LE */
> > > -        mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S));
> > > +        if (likely(!(ctx->insns_flags2 & PPC2_PPE42))) {
> > > +            /* mtmsr does not alter S, ME, or LE */
> > > +            mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << 
> > > MSR_S));
> > > +        }
> > >   
> > >           /*
> > >            * XXX: we need to update nip before the store if we enter


Reply via email to