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>
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 8c081db..20f4565 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -941,8 +941,11 @@
/* 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 @@
#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 @@
/*****************************************************************************/
+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)
{
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 8653151..54eca9b 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -33,9 +33,9 @@
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 @@
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 @@
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 @@
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 @@
{
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;
}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 2c64c63..8e64416 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -464,7 +464,7 @@
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 @@
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;
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index e014c0c..708a840 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -7,6 +7,7 @@
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 @@
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 @@
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 @@
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++)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2673a89..0ac072c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -66,7 +66,7 @@
#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 @@
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 @@
{
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 @@
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 @@
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 @@
} 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 @@
} 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 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
/* 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 @@
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 @@
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 @@
{
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 @@
#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 @@
/*** 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 5df2057..f5fc9b1 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -118,12 +118,12 @@
/* 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 */