summaryrefslogtreecommitdiff
path: root/target-s390x/translate.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2012-09-19 13:50:07 -0700
committerRichard Henderson <rth@twiddle.net>2013-01-05 12:18:45 -0800
commitf24c49c24a4979fe50eff7afe18f371f5809177d (patch)
treeb2b5e77d879cdc2cead9422ec2ab5559b7f85097 /target-s390x/translate.c
parentd074ac6d266129f8f4e2aac5b0e6c39c22964d9a (diff)
downloadqemu-f24c49c24a4979fe50eff7afe18f371f5809177d.tar.gz
target-s390: Optmize emitting discards
While they aren't expensive, they aren't free to process. When we know that the three cc helper variables are dead, don't kill them. Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-s390x/translate.c')
-rw-r--r--target-s390x/translate.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 7f8a5503d9..cfe3766e81 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -367,25 +367,41 @@ static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
return tmp;
}
+static inline bool live_cc_data(DisasContext *s)
+{
+ return (s->cc_op != CC_OP_DYNAMIC
+ && s->cc_op != CC_OP_STATIC
+ && s->cc_op > 3);
+}
+
static inline void gen_op_movi_cc(DisasContext *s, uint32_t val)
{
+ if (live_cc_data(s)) {
+ tcg_gen_discard_i64(cc_src);
+ tcg_gen_discard_i64(cc_dst);
+ tcg_gen_discard_i64(cc_vr);
+ }
s->cc_op = CC_OP_CONST0 + val;
}
static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst)
{
- tcg_gen_discard_i64(cc_src);
+ if (live_cc_data(s)) {
+ tcg_gen_discard_i64(cc_src);
+ tcg_gen_discard_i64(cc_vr);
+ }
tcg_gen_mov_i64(cc_dst, dst);
- tcg_gen_discard_i64(cc_vr);
s->cc_op = op;
}
static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
TCGv_i64 dst)
{
+ if (live_cc_data(s)) {
+ tcg_gen_discard_i64(cc_vr);
+ }
tcg_gen_mov_i64(cc_src, src);
tcg_gen_mov_i64(cc_dst, dst);
- tcg_gen_discard_i64(cc_vr);
s->cc_op = op;
}
@@ -421,9 +437,11 @@ static void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl)
/* CC value is in env->cc_op */
static void set_cc_static(DisasContext *s)
{
- tcg_gen_discard_i64(cc_src);
- tcg_gen_discard_i64(cc_dst);
- tcg_gen_discard_i64(cc_vr);
+ if (live_cc_data(s)) {
+ tcg_gen_discard_i64(cc_src);
+ tcg_gen_discard_i64(cc_dst);
+ tcg_gen_discard_i64(cc_vr);
+ }
s->cc_op = CC_OP_STATIC;
}