target-ppc: Split out SO, OV, CA fields from XER
In preparation for more efficient setting of these fields. Cc: Alexander Graf <agraf@suse.de> Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
		
							parent
							
								
									23ad1d5d3c
								
							
						
					
					
						commit
						da91a00f19
					
				| 
						 | 
				
			
			@ -941,8 +941,11 @@ struct CPUPPCState {
 | 
			
		|||
    /* CFAR */
 | 
			
		||||
    target_ulong cfar;
 | 
			
		||||
#endif
 | 
			
		||||
    /* XER */
 | 
			
		||||
    /* XER (with SO, OV, CA split out) */
 | 
			
		||||
    target_ulong xer;
 | 
			
		||||
    target_ulong so;
 | 
			
		||||
    target_ulong ov;
 | 
			
		||||
    target_ulong ca;
 | 
			
		||||
    /* Reservation address */
 | 
			
		||||
    target_ulong reserve_addr;
 | 
			
		||||
    /* Reservation value */
 | 
			
		||||
| 
						 | 
				
			
			@ -1268,9 +1271,9 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
 | 
			
		|||
#define XER_CA  29
 | 
			
		||||
#define XER_CMP  8
 | 
			
		||||
#define XER_BC   0
 | 
			
		||||
#define xer_so  ((env->xer >> XER_SO)  &    1)
 | 
			
		||||
#define xer_ov  ((env->xer >> XER_OV)  &    1)
 | 
			
		||||
#define xer_ca  ((env->xer >> XER_CA)  &    1)
 | 
			
		||||
#define xer_so  (env->so)
 | 
			
		||||
#define xer_ov  (env->ov)
 | 
			
		||||
#define xer_ca  (env->ca)
 | 
			
		||||
#define xer_cmp ((env->xer >> XER_CMP) & 0xFF)
 | 
			
		||||
#define xer_bc  ((env->xer >> XER_BC)  & 0x7F)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2087,6 +2090,19 @@ enum {
 | 
			
		|||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
static inline target_ulong cpu_read_xer(CPUPPCState *env)
 | 
			
		||||
{
 | 
			
		||||
    return env->xer | (env->so << XER_SO) | (env->ov << XER_OV) | (env->ca << XER_CA);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void cpu_write_xer(CPUPPCState *env, target_ulong xer)
 | 
			
		||||
{
 | 
			
		||||
    env->so = (xer >> XER_SO) & 1;
 | 
			
		||||
    env->ov = (xer >> XER_OV) & 1;
 | 
			
		||||
    env->ca = (xer >> XER_CA) & 1;
 | 
			
		||||
    env->xer = xer & ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
 | 
			
		||||
                                        target_ulong *cs_base, int *flags)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,9 +33,9 @@ uint64_t helper_mulldo(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
 | 
			
		|||
    muls64(&tl, (uint64_t *)&th, arg1, arg2);
 | 
			
		||||
    /* If th != 0 && th != -1, then we had an overflow */
 | 
			
		||||
    if (likely((uint64_t)(th + 1) <= 1)) {
 | 
			
		||||
        env->xer &= ~(1 << XER_OV);
 | 
			
		||||
        env->ov = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
        env->xer |= (1 << XER_OV) | (1 << XER_SO);
 | 
			
		||||
        env->so = env->ov = 1;
 | 
			
		||||
    }
 | 
			
		||||
    return (int64_t)tl;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -64,21 +64,17 @@ target_ulong helper_sraw(CPUPPCState *env, target_ulong value,
 | 
			
		|||
            shift &= 0x1f;
 | 
			
		||||
            ret = (int32_t)value >> shift;
 | 
			
		||||
            if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
 | 
			
		||||
                env->xer &= ~(1 << XER_CA);
 | 
			
		||||
                env->ca = 0;
 | 
			
		||||
            } else {
 | 
			
		||||
                env->xer |= (1 << XER_CA);
 | 
			
		||||
                env->ca = 1;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            ret = (int32_t)value;
 | 
			
		||||
            env->xer &= ~(1 << XER_CA);
 | 
			
		||||
            env->ca = 0;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        ret = (int32_t)value >> 31;
 | 
			
		||||
        if (ret) {
 | 
			
		||||
            env->xer |= (1 << XER_CA);
 | 
			
		||||
        } else {
 | 
			
		||||
            env->xer &= ~(1 << XER_CA);
 | 
			
		||||
        }
 | 
			
		||||
        env->ca = (ret != 0);
 | 
			
		||||
    }
 | 
			
		||||
    return (target_long)ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -94,21 +90,17 @@ target_ulong helper_srad(CPUPPCState *env, target_ulong value,
 | 
			
		|||
            shift &= 0x3f;
 | 
			
		||||
            ret = (int64_t)value >> shift;
 | 
			
		||||
            if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
 | 
			
		||||
                env->xer &= ~(1 << XER_CA);
 | 
			
		||||
                env->ca = 0;
 | 
			
		||||
            } else {
 | 
			
		||||
                env->xer |= (1 << XER_CA);
 | 
			
		||||
                env->ca = 1;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            ret = (int64_t)value;
 | 
			
		||||
            env->xer &= ~(1 << XER_CA);
 | 
			
		||||
            env->ca = 0;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        ret = (int64_t)value >> 63;
 | 
			
		||||
        if (ret) {
 | 
			
		||||
            env->xer |= (1 << XER_CA);
 | 
			
		||||
        } else {
 | 
			
		||||
            env->xer &= ~(1 << XER_CA);
 | 
			
		||||
        }
 | 
			
		||||
        env->ca = (ret != 0);
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -188,16 +180,16 @@ target_ulong helper_divo(CPUPPCState *env, target_ulong arg1,
 | 
			
		|||
 | 
			
		||||
    if (((int32_t)tmp == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
 | 
			
		||||
        (int32_t)arg2 == 0) {
 | 
			
		||||
        env->xer |= (1 << XER_OV) | (1 << XER_SO);
 | 
			
		||||
        env->so = env->ov = 1;
 | 
			
		||||
        env->spr[SPR_MQ] = 0;
 | 
			
		||||
        return INT32_MIN;
 | 
			
		||||
    } else {
 | 
			
		||||
        env->spr[SPR_MQ] = tmp % arg2;
 | 
			
		||||
        tmp /= (int32_t)arg2;
 | 
			
		||||
        if ((int32_t)tmp != tmp) {
 | 
			
		||||
            env->xer |= (1 << XER_OV) | (1 << XER_SO);
 | 
			
		||||
            env->so = env->ov = 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            env->xer &= ~(1 << XER_OV);
 | 
			
		||||
            env->ov = 0;
 | 
			
		||||
        }
 | 
			
		||||
        return tmp;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -221,11 +213,11 @@ target_ulong helper_divso(CPUPPCState *env, target_ulong arg1,
 | 
			
		|||
{
 | 
			
		||||
    if (((int32_t)arg1 == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
 | 
			
		||||
        (int32_t)arg2 == 0) {
 | 
			
		||||
        env->xer |= (1 << XER_OV) | (1 << XER_SO);
 | 
			
		||||
        env->so = env->ov = 1;
 | 
			
		||||
        env->spr[SPR_MQ] = 0;
 | 
			
		||||
        return INT32_MIN;
 | 
			
		||||
    } else {
 | 
			
		||||
        env->xer &= ~(1 << XER_OV);
 | 
			
		||||
        env->ov = 0;
 | 
			
		||||
        env->spr[SPR_MQ] = (int32_t)arg1 % (int32_t)arg2;
 | 
			
		||||
        return (int32_t)arg1 / (int32_t)arg2;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -464,7 +464,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 | 
			
		|||
 | 
			
		||||
    regs.ctr = env->ctr;
 | 
			
		||||
    regs.lr  = env->lr;
 | 
			
		||||
    regs.xer = env->xer;
 | 
			
		||||
    regs.xer = cpu_read_xer(env);
 | 
			
		||||
    regs.msr = env->msr;
 | 
			
		||||
    regs.pc = env->nip;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -566,7 +566,7 @@ int kvm_arch_get_registers(CPUState *cs)
 | 
			
		|||
 | 
			
		||||
    env->ctr = regs.ctr;
 | 
			
		||||
    env->lr = regs.lr;
 | 
			
		||||
    env->xer = regs.xer;
 | 
			
		||||
    cpu_write_xer(env, regs.xer);
 | 
			
		||||
    env->msr = regs.msr;
 | 
			
		||||
    env->nip = regs.pc;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ void cpu_save(QEMUFile *f, void *opaque)
 | 
			
		|||
    CPUPPCState *env = (CPUPPCState *)opaque;
 | 
			
		||||
    unsigned int i, j;
 | 
			
		||||
    uint32_t fpscr;
 | 
			
		||||
    target_ulong xer;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < 32; i++)
 | 
			
		||||
        qemu_put_betls(f, &env->gpr[i]);
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +19,8 @@ void cpu_save(QEMUFile *f, void *opaque)
 | 
			
		|||
    qemu_put_betls(f, &env->ctr);
 | 
			
		||||
    for (i = 0; i < 8; i++)
 | 
			
		||||
        qemu_put_be32s(f, &env->crf[i]);
 | 
			
		||||
    qemu_put_betls(f, &env->xer);
 | 
			
		||||
    xer = cpu_read_xer(env);
 | 
			
		||||
    qemu_put_betls(f, &xer);
 | 
			
		||||
    qemu_put_betls(f, &env->reserve_addr);
 | 
			
		||||
    qemu_put_betls(f, &env->msr);
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +95,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		|||
    unsigned int i, j;
 | 
			
		||||
    target_ulong sdr1;
 | 
			
		||||
    uint32_t fpscr;
 | 
			
		||||
    target_ulong xer;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < 32; i++)
 | 
			
		||||
        qemu_get_betls(f, &env->gpr[i]);
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +107,8 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		|||
    qemu_get_betls(f, &env->ctr);
 | 
			
		||||
    for (i = 0; i < 8; i++)
 | 
			
		||||
        qemu_get_be32s(f, &env->crf[i]);
 | 
			
		||||
    qemu_get_betls(f, &env->xer);
 | 
			
		||||
    qemu_get_betls(f, &xer);
 | 
			
		||||
    cpu_write_xer(env, xer);
 | 
			
		||||
    qemu_get_betls(f, &env->reserve_addr);
 | 
			
		||||
    qemu_get_betls(f, &env->msr);
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ static TCGv cpu_lr;
 | 
			
		|||
#if defined(TARGET_PPC64)
 | 
			
		||||
static TCGv cpu_cfar;
 | 
			
		||||
#endif
 | 
			
		||||
static TCGv cpu_xer;
 | 
			
		||||
static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca;
 | 
			
		||||
static TCGv cpu_reserve;
 | 
			
		||||
static TCGv cpu_fpscr;
 | 
			
		||||
static TCGv_i32 cpu_access_type;
 | 
			
		||||
| 
						 | 
				
			
			@ -158,6 +158,12 @@ void ppc_translate_init(void)
 | 
			
		|||
 | 
			
		||||
    cpu_xer = tcg_global_mem_new(TCG_AREG0,
 | 
			
		||||
                                 offsetof(CPUPPCState, xer), "xer");
 | 
			
		||||
    cpu_so = tcg_global_mem_new(TCG_AREG0,
 | 
			
		||||
                                offsetof(CPUPPCState, so), "SO");
 | 
			
		||||
    cpu_ov = tcg_global_mem_new(TCG_AREG0,
 | 
			
		||||
                                offsetof(CPUPPCState, ov), "OV");
 | 
			
		||||
    cpu_ca = tcg_global_mem_new(TCG_AREG0,
 | 
			
		||||
                                offsetof(CPUPPCState, ca), "CA");
 | 
			
		||||
 | 
			
		||||
    cpu_reserve = tcg_global_mem_new(TCG_AREG0,
 | 
			
		||||
                                     offsetof(CPUPPCState, reserve_addr),
 | 
			
		||||
| 
						 | 
				
			
			@ -592,9 +598,7 @@ static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
 | 
			
		|||
{
 | 
			
		||||
    int l1, l2, l3;
 | 
			
		||||
 | 
			
		||||
    tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_xer);
 | 
			
		||||
    tcg_gen_shri_i32(cpu_crf[crf], cpu_crf[crf], XER_SO);
 | 
			
		||||
    tcg_gen_andi_i32(cpu_crf[crf], cpu_crf[crf], 1);
 | 
			
		||||
    tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
 | 
			
		||||
 | 
			
		||||
    l1 = gen_new_label();
 | 
			
		||||
    l2 = gen_new_label();
 | 
			
		||||
| 
						 | 
				
			
			@ -747,7 +751,7 @@ static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
 | 
			
		|||
 | 
			
		||||
    l1 = gen_new_label();
 | 
			
		||||
    /* Start with XER OV disabled, the most likely case */
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    t0 = tcg_temp_local_new();
 | 
			
		||||
    tcg_gen_xor_tl(t0, arg0, arg1);
 | 
			
		||||
#if defined(TARGET_PPC64)
 | 
			
		||||
| 
						 | 
				
			
			@ -767,7 +771,8 @@ static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
 | 
			
		|||
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
 | 
			
		||||
    else
 | 
			
		||||
        tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
 | 
			
		||||
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 1);
 | 
			
		||||
    tcg_gen_movi_tl(cpu_so, 1);
 | 
			
		||||
    gen_set_label(l1);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -790,7 +795,7 @@ static inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
 | 
			
		|||
        } else {
 | 
			
		||||
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
 | 
			
		||||
        }
 | 
			
		||||
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 1);
 | 
			
		||||
        gen_set_label(l1);
 | 
			
		||||
        tcg_temp_free(t0);
 | 
			
		||||
        tcg_temp_free(t1);
 | 
			
		||||
| 
						 | 
				
			
			@ -802,7 +807,7 @@ static inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
 | 
			
		|||
        } else {
 | 
			
		||||
            tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
 | 
			
		||||
        }
 | 
			
		||||
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 1);
 | 
			
		||||
        gen_set_label(l1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -823,21 +828,18 @@ static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
 | 
			
		|||
 | 
			
		||||
    if (add_ca) {
 | 
			
		||||
        t1 = tcg_temp_local_new();
 | 
			
		||||
        tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
 | 
			
		||||
        tcg_gen_shri_tl(t1, t1, XER_CA);
 | 
			
		||||
        tcg_gen_mov_tl(t1, cpu_ca);
 | 
			
		||||
    } else {
 | 
			
		||||
        TCGV_UNUSED(t1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (compute_ca && compute_ov) {
 | 
			
		||||
        /* Start with XER CA and OV disabled, the most likely case */
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
 | 
			
		||||
    } else if (compute_ca) {
 | 
			
		||||
    if (compute_ca) {
 | 
			
		||||
        /* Start with XER CA disabled, the most likely case */
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
    } else if (compute_ov) {
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (compute_ov) {
 | 
			
		||||
        /* Start with XER OV disabled, the most likely case */
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tcg_gen_add_tl(t0, arg1, arg2);
 | 
			
		||||
| 
						 | 
				
			
			@ -915,8 +917,8 @@ static inline void gen_op_addic(DisasContext *ctx, TCGv ret, TCGv arg1,
 | 
			
		|||
{
 | 
			
		||||
    target_long simm = SIMM(ctx->opcode);
 | 
			
		||||
 | 
			
		||||
    /* Start with XER CA and OV disabled, the most likely case */
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
    /* Start with XER CA disabled, the most likely case */
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
 | 
			
		||||
    if (likely(simm != 0)) {
 | 
			
		||||
        TCGv t0 = tcg_temp_local_new();
 | 
			
		||||
| 
						 | 
				
			
			@ -976,7 +978,7 @@ static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
 | 
			
		|||
        tcg_gen_divu_i32(t0, t0, t1);
 | 
			
		||||
    }
 | 
			
		||||
    if (compute_ov) {
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    }
 | 
			
		||||
    tcg_gen_br(l2);
 | 
			
		||||
    gen_set_label(l1);
 | 
			
		||||
| 
						 | 
				
			
			@ -986,7 +988,8 @@ static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
 | 
			
		|||
        tcg_gen_movi_i32(t0, 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (compute_ov) {
 | 
			
		||||
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ov, 1);
 | 
			
		||||
        tcg_gen_movi_tl(cpu_so, 1);
 | 
			
		||||
    }
 | 
			
		||||
    gen_set_label(l2);
 | 
			
		||||
    tcg_gen_extu_i32_tl(ret, t0);
 | 
			
		||||
| 
						 | 
				
			
			@ -1027,7 +1030,7 @@ static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
 | 
			
		|||
        tcg_gen_divu_i64(ret, arg1, arg2);
 | 
			
		||||
    }
 | 
			
		||||
    if (compute_ov) {
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    }
 | 
			
		||||
    tcg_gen_br(l2);
 | 
			
		||||
    gen_set_label(l1);
 | 
			
		||||
| 
						 | 
				
			
			@ -1037,7 +1040,8 @@ static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
 | 
			
		|||
        tcg_gen_movi_i64(ret, 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (compute_ov) {
 | 
			
		||||
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ov, 1);
 | 
			
		||||
        tcg_gen_movi_tl(cpu_so, 1);
 | 
			
		||||
    }
 | 
			
		||||
    gen_set_label(l2);
 | 
			
		||||
    if (unlikely(Rc(ctx->opcode) != 0))
 | 
			
		||||
| 
						 | 
				
			
			@ -1110,7 +1114,7 @@ static void gen_mullwo(DisasContext *ctx)
 | 
			
		|||
    t1 = tcg_temp_new_i64();
 | 
			
		||||
    l1 = gen_new_label();
 | 
			
		||||
    /* Start with XER OV disabled, the most likely case */
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
#if defined(TARGET_PPC64)
 | 
			
		||||
    tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx->opcode)]);
 | 
			
		||||
    tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx->opcode)]);
 | 
			
		||||
| 
						 | 
				
			
			@ -1127,7 +1131,8 @@ static void gen_mullwo(DisasContext *ctx)
 | 
			
		|||
    tcg_gen_ext32s_i64(t1, t0);
 | 
			
		||||
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
 | 
			
		||||
#endif
 | 
			
		||||
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 1);
 | 
			
		||||
    tcg_gen_movi_tl(cpu_so, 1);
 | 
			
		||||
    gen_set_label(l1);
 | 
			
		||||
    tcg_temp_free_i64(t0);
 | 
			
		||||
    tcg_temp_free_i64(t1);
 | 
			
		||||
| 
						 | 
				
			
			@ -1206,13 +1211,14 @@ static inline void gen_op_arith_neg(DisasContext *ctx, TCGv ret, TCGv arg1,
 | 
			
		|||
    }
 | 
			
		||||
    tcg_gen_neg_tl(ret, arg1);
 | 
			
		||||
    if (ov_check) {
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    }
 | 
			
		||||
    tcg_gen_br(l2);
 | 
			
		||||
    gen_set_label(l1);
 | 
			
		||||
    tcg_gen_mov_tl(ret, t0);
 | 
			
		||||
    if (ov_check) {
 | 
			
		||||
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ov, 1);
 | 
			
		||||
        tcg_gen_movi_tl(cpu_so, 1);
 | 
			
		||||
    }
 | 
			
		||||
    gen_set_label(l2);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
| 
						 | 
				
			
			@ -1246,21 +1252,18 @@ static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
 | 
			
		|||
 | 
			
		||||
    if (add_ca) {
 | 
			
		||||
        t1 = tcg_temp_local_new();
 | 
			
		||||
        tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
 | 
			
		||||
        tcg_gen_shri_tl(t1, t1, XER_CA);
 | 
			
		||||
        tcg_gen_mov_tl(t1, cpu_ca);
 | 
			
		||||
    } else {
 | 
			
		||||
        TCGV_UNUSED(t1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (compute_ca && compute_ov) {
 | 
			
		||||
        /* Start with XER CA and OV disabled, the most likely case */
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
 | 
			
		||||
    } else if (compute_ca) {
 | 
			
		||||
    if (compute_ca) {
 | 
			
		||||
        /* Start with XER CA disabled, the most likely case */
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
    } else if (compute_ov) {
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (compute_ov) {
 | 
			
		||||
        /* Start with XER OV disabled, the most likely case */
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (add_ca) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1326,8 +1329,8 @@ GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
 | 
			
		|||
/* subfic */
 | 
			
		||||
static void gen_subfic(DisasContext *ctx)
 | 
			
		||||
{
 | 
			
		||||
    /* Start with XER CA and OV disabled, the most likely case */
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
    /* Start with XER CA disabled, the most likely case */
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
    TCGv t0 = tcg_temp_local_new();
 | 
			
		||||
    TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
 | 
			
		||||
    tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
 | 
			
		||||
| 
						 | 
				
			
			@ -1891,17 +1894,17 @@ static void gen_srawi(DisasContext *ctx)
 | 
			
		|||
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
 | 
			
		||||
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
 | 
			
		||||
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
 | 
			
		||||
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 1);
 | 
			
		||||
        tcg_gen_br(l2);
 | 
			
		||||
        gen_set_label(l1);
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
        gen_set_label(l2);
 | 
			
		||||
        tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
 | 
			
		||||
        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], t0, sh);
 | 
			
		||||
        tcg_temp_free(t0);
 | 
			
		||||
    } else {
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (unlikely(Rc(ctx->opcode) != 0))
 | 
			
		||||
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 | 
			
		||||
| 
						 | 
				
			
			@ -1973,16 +1976,16 @@ static inline void gen_sradi(DisasContext *ctx, int n)
 | 
			
		|||
        tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
 | 
			
		||||
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
 | 
			
		||||
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
 | 
			
		||||
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 1);
 | 
			
		||||
        tcg_gen_br(l2);
 | 
			
		||||
        gen_set_label(l1);
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
        gen_set_label(l2);
 | 
			
		||||
        tcg_temp_free(t0);
 | 
			
		||||
        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
 | 
			
		||||
    } else {
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
 | 
			
		||||
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
        tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (unlikely(Rc(ctx->opcode) != 0))
 | 
			
		||||
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 | 
			
		||||
| 
						 | 
				
			
			@ -3170,9 +3173,7 @@ static void gen_stwcx_(DisasContext *ctx)
 | 
			
		|||
    {
 | 
			
		||||
        int l1;
 | 
			
		||||
 | 
			
		||||
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
 | 
			
		||||
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
 | 
			
		||||
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
 | 
			
		||||
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
 | 
			
		||||
        l1 = gen_new_label();
 | 
			
		||||
        tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
 | 
			
		||||
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
 | 
			
		||||
| 
						 | 
				
			
			@ -3213,9 +3214,7 @@ static void gen_stdcx_(DisasContext *ctx)
 | 
			
		|||
#else
 | 
			
		||||
    {
 | 
			
		||||
        int l1;
 | 
			
		||||
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
 | 
			
		||||
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
 | 
			
		||||
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
 | 
			
		||||
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
 | 
			
		||||
        l1 = gen_new_label();
 | 
			
		||||
        tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
 | 
			
		||||
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
 | 
			
		||||
| 
						 | 
				
			
			@ -3791,12 +3790,55 @@ static void gen_tdi(DisasContext *ctx)
 | 
			
		|||
 | 
			
		||||
/***                          Processor control                            ***/
 | 
			
		||||
 | 
			
		||||
static void gen_read_xer(TCGv dst)
 | 
			
		||||
{
 | 
			
		||||
    TCGv t0 = tcg_temp_new();
 | 
			
		||||
    TCGv t1 = tcg_temp_new();
 | 
			
		||||
    TCGv t2 = tcg_temp_new();
 | 
			
		||||
    tcg_gen_mov_tl(dst, cpu_xer);
 | 
			
		||||
    tcg_gen_shli_tl(t0, cpu_so, XER_SO);
 | 
			
		||||
    tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
 | 
			
		||||
    tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
 | 
			
		||||
    tcg_gen_or_tl(t0, t0, t1);
 | 
			
		||||
    tcg_gen_or_tl(dst, dst, t2);
 | 
			
		||||
    tcg_gen_or_tl(dst, dst, t0);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
    tcg_temp_free(t1);
 | 
			
		||||
    tcg_temp_free(t2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gen_write_xer(TCGv src)
 | 
			
		||||
{
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, src,
 | 
			
		||||
                    ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA)));
 | 
			
		||||
    tcg_gen_shri_tl(cpu_so, src, XER_SO);
 | 
			
		||||
    tcg_gen_shri_tl(cpu_ov, src, XER_OV);
 | 
			
		||||
    tcg_gen_shri_tl(cpu_ca, src, XER_CA);
 | 
			
		||||
    tcg_gen_andi_tl(cpu_so, cpu_so, 1);
 | 
			
		||||
    tcg_gen_andi_tl(cpu_ov, cpu_ov, 1);
 | 
			
		||||
    tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* mcrxr */
 | 
			
		||||
static void gen_mcrxr(DisasContext *ctx)
 | 
			
		||||
{
 | 
			
		||||
    tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
 | 
			
		||||
    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
 | 
			
		||||
    TCGv_i32 t0 = tcg_temp_new_i32();
 | 
			
		||||
    TCGv_i32 t1 = tcg_temp_new_i32();
 | 
			
		||||
    TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
 | 
			
		||||
 | 
			
		||||
    tcg_gen_trunc_tl_i32(t0, cpu_so);
 | 
			
		||||
    tcg_gen_trunc_tl_i32(t1, cpu_ov);
 | 
			
		||||
    tcg_gen_trunc_tl_i32(dst, cpu_ca);
 | 
			
		||||
    tcg_gen_shri_i32(t0, t0, 2);
 | 
			
		||||
    tcg_gen_shri_i32(t1, t1, 1);
 | 
			
		||||
    tcg_gen_or_i32(dst, dst, t0);
 | 
			
		||||
    tcg_gen_or_i32(dst, dst, t1);
 | 
			
		||||
    tcg_temp_free_i32(t0);
 | 
			
		||||
    tcg_temp_free_i32(t1);
 | 
			
		||||
 | 
			
		||||
    tcg_gen_movi_tl(cpu_so, 0);
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* mfcr mfocrf */
 | 
			
		||||
| 
						 | 
				
			
			@ -4526,10 +4568,11 @@ static void gen_abso(DisasContext *ctx)
 | 
			
		|||
    int l2 = gen_new_label();
 | 
			
		||||
    int l3 = gen_new_label();
 | 
			
		||||
    /* Start with XER OV disabled, the most likely case */
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
 | 
			
		||||
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
 | 
			
		||||
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 1);
 | 
			
		||||
    tcg_gen_movi_tl(cpu_so, 1);
 | 
			
		||||
    tcg_gen_br(l2);
 | 
			
		||||
    gen_set_label(l1);
 | 
			
		||||
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
 | 
			
		||||
| 
						 | 
				
			
			@ -4610,7 +4653,7 @@ static void gen_dozo(DisasContext *ctx)
 | 
			
		|||
    TCGv t1 = tcg_temp_new();
 | 
			
		||||
    TCGv t2 = tcg_temp_new();
 | 
			
		||||
    /* Start with XER OV disabled, the most likely case */
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
 | 
			
		||||
    tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
 | 
			
		||||
    tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
 | 
			
		||||
| 
						 | 
				
			
			@ -4618,7 +4661,8 @@ static void gen_dozo(DisasContext *ctx)
 | 
			
		|||
    tcg_gen_andc_tl(t1, t1, t2);
 | 
			
		||||
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
 | 
			
		||||
    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
 | 
			
		||||
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 1);
 | 
			
		||||
    tcg_gen_movi_tl(cpu_so, 1);
 | 
			
		||||
    tcg_gen_br(l2);
 | 
			
		||||
    gen_set_label(l1);
 | 
			
		||||
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -4736,7 +4780,7 @@ static void gen_mulo(DisasContext *ctx)
 | 
			
		|||
    TCGv_i64 t1 = tcg_temp_new_i64();
 | 
			
		||||
    TCGv t2 = tcg_temp_new();
 | 
			
		||||
    /* Start with XER OV disabled, the most likely case */
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
 | 
			
		||||
    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
 | 
			
		||||
    tcg_gen_mul_i64(t0, t0, t1);
 | 
			
		||||
| 
						 | 
				
			
			@ -4746,7 +4790,8 @@ static void gen_mulo(DisasContext *ctx)
 | 
			
		|||
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
 | 
			
		||||
    tcg_gen_ext32s_i64(t1, t0);
 | 
			
		||||
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
 | 
			
		||||
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 1);
 | 
			
		||||
    tcg_gen_movi_tl(cpu_so, 1);
 | 
			
		||||
    gen_set_label(l1);
 | 
			
		||||
    tcg_temp_free_i64(t0);
 | 
			
		||||
    tcg_temp_free_i64(t1);
 | 
			
		||||
| 
						 | 
				
			
			@ -4782,7 +4827,7 @@ static void gen_nabso(DisasContext *ctx)
 | 
			
		|||
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
 | 
			
		||||
    gen_set_label(l2);
 | 
			
		||||
    /* nabs never overflows */
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
    if (unlikely(Rc(ctx->opcode) != 0))
 | 
			
		||||
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -4959,10 +5004,10 @@ static void gen_sraiq(DisasContext *ctx)
 | 
			
		|||
    tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
 | 
			
		||||
    tcg_gen_or_tl(t0, t0, t1);
 | 
			
		||||
    gen_store_spr(SPR_MQ, t0);
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
 | 
			
		||||
    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
 | 
			
		||||
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ca, 1);
 | 
			
		||||
    gen_set_label(l1);
 | 
			
		||||
    tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
| 
						 | 
				
			
			@ -4993,10 +5038,10 @@ static void gen_sraq(DisasContext *ctx)
 | 
			
		|||
    gen_set_label(l1);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
 | 
			
		||||
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ca, 0);
 | 
			
		||||
    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
 | 
			
		||||
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
 | 
			
		||||
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
 | 
			
		||||
    tcg_gen_movi_tl(cpu_ca, 1);
 | 
			
		||||
    gen_set_label(l2);
 | 
			
		||||
    tcg_temp_free(t1);
 | 
			
		||||
    tcg_temp_free(t2);
 | 
			
		||||
| 
						 | 
				
			
			@ -5565,7 +5610,7 @@ static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
 | 
			
		|||
 | 
			
		||||
            if (opc3 & 0x10) {
 | 
			
		||||
                /* Start with XER OV disabled, the most likely case */
 | 
			
		||||
                tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
 | 
			
		||||
                tcg_gen_movi_tl(cpu_ov, 0);
 | 
			
		||||
            }
 | 
			
		||||
            if (opc3 & 0x01) {
 | 
			
		||||
                /* Signed */
 | 
			
		||||
| 
						 | 
				
			
			@ -5588,7 +5633,8 @@ static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
 | 
			
		|||
            }
 | 
			
		||||
            if (opc3 & 0x10) {
 | 
			
		||||
                /* Check overflow */
 | 
			
		||||
                tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
 | 
			
		||||
                tcg_gen_movi_tl(cpu_ov, 1);
 | 
			
		||||
                tcg_gen_movi_tl(cpu_so, 1);
 | 
			
		||||
            }
 | 
			
		||||
            gen_set_label(l1);
 | 
			
		||||
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
 | 
			
		||||
| 
						 | 
				
			
			@ -5976,9 +6022,7 @@ static void gen_tlbsx_40x(DisasContext *ctx)
 | 
			
		|||
    tcg_temp_free(t0);
 | 
			
		||||
    if (Rc(ctx->opcode)) {
 | 
			
		||||
        int l1 = gen_new_label();
 | 
			
		||||
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
 | 
			
		||||
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
 | 
			
		||||
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
 | 
			
		||||
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
 | 
			
		||||
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
 | 
			
		||||
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
 | 
			
		||||
        gen_set_label(l1);
 | 
			
		||||
| 
						 | 
				
			
			@ -6059,9 +6103,7 @@ static void gen_tlbsx_440(DisasContext *ctx)
 | 
			
		|||
    tcg_temp_free(t0);
 | 
			
		||||
    if (Rc(ctx->opcode)) {
 | 
			
		||||
        int l1 = gen_new_label();
 | 
			
		||||
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
 | 
			
		||||
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
 | 
			
		||||
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
 | 
			
		||||
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
 | 
			
		||||
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
 | 
			
		||||
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
 | 
			
		||||
        gen_set_label(l1);
 | 
			
		||||
| 
						 | 
				
			
			@ -9410,7 +9452,7 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
 | 
			
		|||
 | 
			
		||||
    cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
 | 
			
		||||
                TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
 | 
			
		||||
                env->nip, env->lr, env->ctr, env->xer);
 | 
			
		||||
                env->nip, env->lr, env->ctr, cpu_read_xer(env));
 | 
			
		||||
    cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
 | 
			
		||||
                TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
 | 
			
		||||
                env->hflags, env->mmu_idx);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,12 +118,12 @@ static void spr_write_clear (void *opaque, int sprn, int gprn)
 | 
			
		|||
/* XER */
 | 
			
		||||
static void spr_read_xer (void *opaque, int gprn, int sprn)
 | 
			
		||||
{
 | 
			
		||||
    tcg_gen_mov_tl(cpu_gpr[gprn], cpu_xer);
 | 
			
		||||
    gen_read_xer(cpu_gpr[gprn]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void spr_write_xer (void *opaque, int sprn, int gprn)
 | 
			
		||||
{
 | 
			
		||||
    tcg_gen_mov_tl(cpu_xer, cpu_gpr[gprn]);
 | 
			
		||||
    gen_write_xer(cpu_gpr[gprn]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* LR */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue