[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 145/147] target-s390: Optimize ADDC/SUBB
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 145/147] target-s390: Optimize ADDC/SUBB |
Date: |
Thu, 27 Sep 2012 18:22:36 -0700 |
Giving the proper mask to disas_jcc allows us to generate an inline
comparison generating the carry/borrow with setcond.
In the very worst case, when we must use the external helper to compute
a value for CC, we generate (cc > 1) instead of (cc >> 1), which is only
very slightly slower on common cpus.
In the very best case, when the CC comes from a COMPARE insn and the
compiler is using ALCG with zero, everything folds out to become just
the setcond that the compiler wanted.
Signed-off-by: Richard Henderson <address@hidden>
---
target-s390x/translate.c | 56 ++++++++++++++++++++++++++++++++----------------
1 file changed, 37 insertions(+), 19 deletions(-)
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index de9ae97..e1888a3 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -1344,18 +1344,28 @@ static ExitStatus op_add(DisasContext *s, DisasOps *o)
static ExitStatus op_addc(DisasContext *s, DisasOps *o)
{
- TCGv_i64 cc;
+ DisasCompare cmp;
+ TCGv_i64 carry;
tcg_gen_add_i64(o->out, o->in1, o->in2);
- /* XXX possible optimization point */
- gen_op_calc_cc(s);
- cc = tcg_temp_new_i64();
- tcg_gen_extu_i32_i64(cc, cc_op);
- tcg_gen_shri_i64(cc, cc, 1);
+ /* The carry flag is the msb of CC, therefore the branch mask that would
+ create that comparison is 3. Feeding the generated comparison to
+ setcond produces the carry flag that we desire. */
+ disas_jcc(s, &cmp, 3);
+ carry = tcg_temp_new_i64();
+ if (cmp.is_64) {
+ tcg_gen_setcond_i64(cmp.cond, carry, cmp.u.s64.a, cmp.u.s64.b);
+ } else {
+ TCGv_i32 t = tcg_temp_new_i32();
+ tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b);
+ tcg_gen_extu_i32_i64(carry, t);
+ tcg_temp_free_i32(t);
+ }
+ free_compare(&cmp);
- tcg_gen_add_i64(o->out, o->out, cc);
- tcg_temp_free_i64(cc);
+ tcg_gen_add_i64(o->out, o->out, carry);
+ tcg_temp_free_i64(carry);
return NO_EXIT;
}
@@ -3397,19 +3407,27 @@ static ExitStatus op_sub(DisasContext *s, DisasOps *o)
static ExitStatus op_subb(DisasContext *s, DisasOps *o)
{
- TCGv_i64 cc;
+ DisasCompare cmp;
+ TCGv_i64 borrow;
- assert(!o->g_in2);
- tcg_gen_not_i64(o->in2, o->in2);
- tcg_gen_add_i64(o->out, o->in1, o->in2);
+ tcg_gen_sub_i64(o->out, o->in1, o->in2);
- /* XXX possible optimization point */
- gen_op_calc_cc(s);
- cc = tcg_temp_new_i64();
- tcg_gen_extu_i32_i64(cc, cc_op);
- tcg_gen_shri_i64(cc, cc, 1);
- tcg_gen_add_i64(o->out, o->out, cc);
- tcg_temp_free_i64(cc);
+ /* The !borrow flag is the msb of CC. Since we want the inverse of
+ that, we ask for a comparison of CC=0 | CC=1 -> mask of 8 | 4. */
+ disas_jcc(s, &cmp, 8 | 4);
+ borrow = tcg_temp_new_i64();
+ if (cmp.is_64) {
+ tcg_gen_setcond_i64(cmp.cond, borrow, cmp.u.s64.a, cmp.u.s64.b);
+ } else {
+ TCGv_i32 t = tcg_temp_new_i32();
+ tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b);
+ tcg_gen_extu_i32_i64(borrow, t);
+ tcg_temp_free_i32(t);
+ }
+ free_compare(&cmp);
+
+ tcg_gen_sub_i64(o->out, o->out, borrow);
+ tcg_temp_free_i64(borrow);
return NO_EXIT;
}
--
1.7.11.4
- [Qemu-devel] [PATCH 135/147] softfloat: Fix uint64_to_float64, (continued)
- [Qemu-devel] [PATCH 135/147] softfloat: Fix uint64_to_float64, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 136/147] softfloat: Implement uint64_to_float128, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 137/147] target-s390: Use uint64_to_float128, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 138/147] target-s390: Implement SET ROUNDING MODE, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 139/147] target-s390: Implement LOAD/SET FP AND SIGNAL, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 140/147] target-s390: Fix cpu_clone_regs, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 141/147] target-s390: Optimize XC, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 142/147] target-s390: Optmize emitting discards, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 143/147] target-s390: Tidy comparisons, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 144/147] target-s390: Optimize ADDU/SUBU CC testing, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 145/147] target-s390: Optimize ADDC/SUBB,
Richard Henderson <=
- [Qemu-devel] [PATCH 146/147] target-s390: Optimize get_address, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 147/147] target-s390: Perform COMPARE AND SWAP inline, Richard Henderson, 2012/09/27