aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorSandipan Das <sandipan@linux.vnet.ibm.com>2017-10-06 12:12:44 +0530
committerDavid Gibson <david@gibson.dropbear.id.au>2017-10-17 10:34:00 +1100
commitaf1c259f6d4f1c6b0af22a0ff0b764c4ef3ef85e (patch)
treec35aef8362fa07c002f014c4866070cf8c6bc2e7 /target
parent1ed9c8af501f8d1bdf5a8725a038527be059f54d (diff)
downloadqemu-af1c259f6d4f1c6b0af22a0ff0b764c4ef3ef85e.zip
qemu-af1c259f6d4f1c6b0af22a0ff0b764c4ef3ef85e.tar.gz
qemu-af1c259f6d4f1c6b0af22a0ff0b764c4ef3ef85e.tar.bz2
target/ppc: Fix carry flag setting for shift algebraic instructions
For POWER ISA v3.0, the XER bit CA32 needs to be set by the shift right algebraic instructions whenever the CA bit is to be set. This change affects the following instructions: * Shift Right Algebraic Word (sraw[.]) * Shift Right Algebraic Word Immediate (srawi[.]) * Shift Right Algebraic Doubleword (srad[.]) * Shift Right Algebraic Doubleword Immediate (sradi[.]) Signed-off-by: Sandipan Das <sandipan@linux.vnet.ibm.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target')
-rw-r--r--target/ppc/int_helper.c16
-rw-r--r--target/ppc/translate.c12
2 files changed, 20 insertions, 8 deletions
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index da4e1a6..1c013a0 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -219,17 +219,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->ca = 0;
+ env->ca32 = env->ca = 0;
} else {
- env->ca = 1;
+ env->ca32 = env->ca = 1;
}
} else {
ret = (int32_t)value;
- env->ca = 0;
+ env->ca32 = env->ca = 0;
}
} else {
ret = (int32_t)value >> 31;
- env->ca = (ret != 0);
+ env->ca32 = env->ca = (ret != 0);
}
return (target_long)ret;
}
@@ -245,17 +245,17 @@ target_ulong helper_srad(CPUPPCState *env, target_ulong value,
shift &= 0x3f;
ret = (int64_t)value >> shift;
if (likely(ret >= 0 || (value & ((1ULL << shift) - 1)) == 0)) {
- env->ca = 0;
+ env->ca32 = env->ca = 0;
} else {
- env->ca = 1;
+ env->ca32 = env->ca = 1;
}
} else {
ret = (int64_t)value;
- env->ca = 0;
+ env->ca32 = env->ca = 0;
}
} else {
ret = (int64_t)value >> 63;
- env->ca = (ret != 0);
+ env->ca32 = env->ca = (ret != 0);
}
return ret;
}
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 606b605..a81ff69 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -2181,6 +2181,9 @@ static void gen_srawi(DisasContext *ctx)
if (sh == 0) {
tcg_gen_ext32s_tl(dst, src);
tcg_gen_movi_tl(cpu_ca, 0);
+ if (is_isa300(ctx)) {
+ tcg_gen_movi_tl(cpu_ca32, 0);
+ }
} else {
TCGv t0;
tcg_gen_ext32s_tl(dst, src);
@@ -2190,6 +2193,9 @@ static void gen_srawi(DisasContext *ctx)
tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
tcg_temp_free(t0);
tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
+ if (is_isa300(ctx)) {
+ tcg_gen_mov_tl(cpu_ca32, cpu_ca);
+ }
tcg_gen_sari_tl(dst, dst, sh);
}
if (unlikely(Rc(ctx->opcode) != 0)) {
@@ -2259,6 +2265,9 @@ static inline void gen_sradi(DisasContext *ctx, int n)
if (sh == 0) {
tcg_gen_mov_tl(dst, src);
tcg_gen_movi_tl(cpu_ca, 0);
+ if (is_isa300(ctx)) {
+ tcg_gen_movi_tl(cpu_ca32, 0);
+ }
} else {
TCGv t0;
tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
@@ -2267,6 +2276,9 @@ static inline void gen_sradi(DisasContext *ctx, int n)
tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
tcg_temp_free(t0);
tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
+ if (is_isa300(ctx)) {
+ tcg_gen_mov_tl(cpu_ca32, cpu_ca);
+ }
tcg_gen_sari_tl(dst, src, sh);
}
if (unlikely(Rc(ctx->opcode) != 0)) {