diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 9d4e43cf1fca88f38051566336ae80429dfe2de5..5282533b385874fff54e871c5c5e29998af1c06c 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2415,6 +2415,16 @@ static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr) return msr & (1ULL << MSR_SF); } +/** + * Check whether register rx is in the range between start and + * start + nregs (as needed by the LSWX and LSWI instructions) + */ +static inline bool lsw_reg_in_range(int start, int nregs, int rx) +{ + return (start + nregs <= 32 && rx >= start && rx < start + nregs) || + (start + nregs > 32 && (rx >= start || rx < start + nregs - 32)); +} + extern void (*cpu_ppc_hypercall)(PowerPCCPU *); #include "exec/exec-all.h" diff --git a/target-ppc/machine.c b/target-ppc/machine.c index 692121e983190c56088375335bc692715faba749..46684fb9337229e5fd94285ef3a85ec945390c09 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -136,7 +136,7 @@ static void cpu_pre_save(void *opaque) env->spr[SPR_LR] = env->lr; env->spr[SPR_CTR] = env->ctr; - env->spr[SPR_XER] = env->xer; + env->spr[SPR_XER] = cpu_read_xer(env); #if defined(TARGET_PPC64) env->spr[SPR_CFAR] = env->cfar; #endif diff --git a/target-ppc/mem_helper.c b/target-ppc/mem_helper.c index 581d9faa2309024fbbf72f26cf2c7029c3879bd0..6d584c91268ee204aa44a65622a9bc6eb84e1066 100644 --- a/target-ppc/mem_helper.c +++ b/target-ppc/mem_helper.c @@ -102,8 +102,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg, { if (likely(xer_bc != 0)) { int num_used_regs = (xer_bc + 3) / 4; - if (unlikely((ra != 0 && reg < ra && (reg + num_used_regs) > ra) || - (reg < rb && (reg + num_used_regs) > rb))) { + if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) || + lsw_reg_in_range(reg, num_used_regs, rb))) { + env->nip += 4; /* Compensate the "nip - 4" from gen_lswx() */ helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX); diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 6f0e7b4face65f020d0ac6309d4cae59f98df58e..b3860ecdea9cdbf8a9ade6a664f767f729bf08bb 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -3227,10 +3227,8 @@ static void gen_lswi(DisasContext *ctx) if (nb == 0) nb = 32; - nr = nb / 4; - if (unlikely(((start + nr) > 32 && - start <= ra && (start + nr - 32) > ra) || - ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) { + nr = (nb + 3) / 4; + if (unlikely(lsw_reg_in_range(start, nr, ra))) { gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX); return; }