All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: Blue Swirl <blauwirbel@gmail.com>
Subject: [Qemu-devel] [PATCH 18/23] target-sparc: Move taddcctv and tsubcctv out of line
Date: Fri,  5 Oct 2012 16:55:05 -0700	[thread overview]
Message-ID: <1349481310-9237-19-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1349481310-9237-1-git-send-email-rth@twiddle.net>

The branches around the exception are maintaining an otherwise
unnecessary use of local temps for the cpu destination.

Note that gen_op_t{add,sub}_cc were identical to gen_op_{add,sub}_cc.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-sparc/helper.c    |  58 +++++++++++++++++++++++++
 target-sparc/helper.h    |   2 +
 target-sparc/translate.c | 108 +++--------------------------------------------
 3 files changed, 66 insertions(+), 102 deletions(-)

diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 4555d2b..556ac28 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -167,3 +167,61 @@ uint64_t helper_udivx(CPUSPARCState *env, uint64_t a, uint64_t b)
     return a / b;
 }
 #endif
+
+target_ulong helper_taddcctv(CPUSPARCState *env, target_ulong src1,
+                             target_ulong src2)
+{
+    target_ulong dst;
+
+    /* Tag overflow occurs if either input has bits 0 or 1 set.  */
+    if ((src1 | src2) & 3) {
+        goto tag_overflow;
+    }
+
+    dst = src1 + src2;
+
+    /* Tag overflow occurs if the addition overflows.  */
+    if (~(src1 ^ src2) & (src1 ^ dst) & (1u << 31)) {
+        goto tag_overflow;
+    }
+
+    /* Only modify the CC after any exceptions have been generated.  */
+    env->cc_op = CC_OP_TADDTV;
+    env->cc_src = src1;
+    env->cc_src2 = src2;
+    env->cc_dst = dst;
+    return dst;
+
+ tag_overflow:
+    cpu_restore_state2(env, GETPC());
+    helper_raise_exception(env, TT_TOVF);
+}
+
+target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1,
+                             target_ulong src2)
+{
+    target_ulong dst;
+
+    /* Tag overflow occurs if either input has bits 0 or 1 set.  */
+    if ((src1 | src2) & 3) {
+        goto tag_overflow;
+    }
+
+    dst = src1 - src2;
+
+    /* Tag overflow occurs if the subtraction overflows.  */
+    if ((src1 ^ src2) & (src1 ^ dst) & (1u << 31)) {
+        goto tag_overflow;
+    }
+
+    /* Only modify the CC after any exceptions have been generated.  */
+    env->cc_op = CC_OP_TSUBTV;
+    env->cc_src = src1;
+    env->cc_src2 = src2;
+    env->cc_dst = dst;
+    return dst;
+
+ tag_overflow:
+    cpu_restore_state2(env, GETPC());
+    helper_raise_exception(env, TT_TOVF);
+}
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index 827df67..e1ae3c7 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -38,6 +38,8 @@ DEF_HELPER_3(udiv, tl, env, tl, tl)
 DEF_HELPER_3(udiv_cc, tl, env, tl, tl)
 DEF_HELPER_3(sdiv, tl, env, tl, tl)
 DEF_HELPER_3(sdiv_cc, tl, env, tl, tl)
+DEF_HELPER_3(taddcctv, tl, env, tl, tl)
+DEF_HELPER_3(tsubcctv, tl, env, tl, tl)
 #ifdef TARGET_SPARC64
 DEF_HELPER_3(sdivx, s64, env, s64, s64)
 DEF_HELPER_3(udivx, i64, env, i64, i64)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 111c025..98efb84 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -336,43 +336,6 @@ static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src)
     tcg_gen_andi_tl(reg, reg, 0x1);
 }
 
-static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
-{
-    TCGv r_temp;
-    TCGv_i32 r_const;
-    int l1;
-
-    l1 = gen_new_label();
-
-    r_temp = tcg_temp_new();
-    tcg_gen_xor_tl(r_temp, src1, src2);
-    tcg_gen_not_tl(r_temp, r_temp);
-    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
-    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
-    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
-    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
-    r_const = tcg_const_i32(TT_TOVF);
-    gen_helper_raise_exception(cpu_env, r_const);
-    tcg_temp_free_i32(r_const);
-    gen_set_label(l1);
-    tcg_temp_free(r_temp);
-}
-
-static inline void gen_tag_tv(TCGv src1, TCGv src2)
-{
-    int l1;
-    TCGv_i32 r_const;
-
-    l1 = gen_new_label();
-    tcg_gen_or_tl(cpu_tmp0, src1, src2);
-    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
-    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
-    r_const = tcg_const_i32(TT_TOVF);
-    gen_helper_raise_exception(cpu_env, r_const);
-    tcg_temp_free_i32(r_const);
-    gen_set_label(l1);
-}
-
 static inline void gen_op_addi_cc(TCGv dst, TCGv src1, target_long src2)
 {
     tcg_gen_mov_tl(cpu_cc_src, src1);
@@ -517,45 +480,6 @@ static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
     }
 }
 
-static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
-{
-    tcg_gen_mov_tl(cpu_cc_src, src1);
-    tcg_gen_mov_tl(cpu_cc_src2, src2);
-    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
-    tcg_gen_mov_tl(dst, cpu_cc_dst);
-}
-
-static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
-{
-    tcg_gen_mov_tl(cpu_cc_src, src1);
-    tcg_gen_mov_tl(cpu_cc_src2, src2);
-    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
-    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
-    gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
-    tcg_gen_mov_tl(dst, cpu_cc_dst);
-}
-
-static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
-{
-    TCGv r_temp;
-    TCGv_i32 r_const;
-    int l1;
-
-    l1 = gen_new_label();
-
-    r_temp = tcg_temp_new();
-    tcg_gen_xor_tl(r_temp, src1, src2);
-    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
-    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
-    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
-    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
-    r_const = tcg_const_i32(TT_TOVF);
-    gen_helper_raise_exception(cpu_env, r_const);
-    tcg_temp_free_i32(r_const);
-    gen_set_label(l1);
-    tcg_temp_free(r_temp);
-}
-
 static inline void gen_op_subi_cc(TCGv dst, TCGv src1, target_long src2, DisasContext *dc)
 {
     tcg_gen_mov_tl(cpu_cc_src, src1);
@@ -656,24 +580,6 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
     }
 }
 
-static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
-{
-    tcg_gen_mov_tl(cpu_cc_src, src1);
-    tcg_gen_mov_tl(cpu_cc_src2, src2);
-    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
-    tcg_gen_mov_tl(dst, cpu_cc_dst);
-}
-
-static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
-{
-    tcg_gen_mov_tl(cpu_cc_src, src1);
-    tcg_gen_mov_tl(cpu_cc_src2, src2);
-    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
-    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
-    gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
-    tcg_gen_mov_tl(dst, cpu_cc_dst);
-}
-
 static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
 {
     TCGv r_temp;
@@ -3602,29 +3508,27 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     cpu_src2 = get_src2(insn, cpu_src2);
                     switch (xop) {
                     case 0x20: /* taddcc */
-                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
+                        gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
                         gen_movl_TN_reg(rd, cpu_dst);
                         tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
                         dc->cc_op = CC_OP_TADD;
                         break;
                     case 0x21: /* tsubcc */
-                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
+                        gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
                         gen_movl_TN_reg(rd, cpu_dst);
                         tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
                         dc->cc_op = CC_OP_TSUB;
                         break;
                     case 0x22: /* taddcctv */
-                        save_state(dc);
-                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
+                        gen_helper_taddcctv(cpu_dst, cpu_env,
+                                            cpu_src1, cpu_src2);
                         gen_movl_TN_reg(rd, cpu_dst);
-                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADDTV);
                         dc->cc_op = CC_OP_TADDTV;
                         break;
                     case 0x23: /* tsubcctv */
-                        save_state(dc);
-                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
+                        gen_helper_tsubcctv(cpu_dst, cpu_env,
+                                            cpu_src1, cpu_src2);
                         gen_movl_TN_reg(rd, cpu_dst);
-                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUBTV);
                         dc->cc_op = CC_OP_TSUBTV;
                         break;
                     case 0x24: /* mulscc */
-- 
1.7.11.4

  parent reply	other threads:[~2012-10-05 23:55 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-05 23:54 [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 01/23] target-sparc: Tidy cpu_dump_state Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 02/23] target-sparc: Make CPU_LOG_INT useful by default Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 03/23] target-sparc: Tidy do_branch interfaces Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 04/23] target-sparc: Tidy flush_cond interface Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 05/23] target-sparc: Tidy gen_trap_ifnofpu interface Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 06/23] target-sparc: Tidy save_state interface Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 07/23] target-sparc: Tidy gen_mov_pc_npc interface Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 08/23] target-sparc: Tidy save_npc interface Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 09/23] target-sparc: Tidy gen_generic_branch interface Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 10/23] target-sparc: Introduce DisasCompare and functions to generate it Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 11/23] target-sparc: Use DisasCompare in Tcc Richard Henderson
2012-10-05 23:54 ` [Qemu-devel] [PATCH 12/23] target-sparc: Use DisasCompare and movcond in FMOVR, FMOVCC Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 13/23] target-sparc: Use DisasCompare and movcond in MOVCC Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 14/23] target-sparc: Use DisasCompare and movcond in MOVR Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 15/23] target-sparc: Use movcond in gen_generic_branch Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 16/23] target-sparc: Move sdivx and udivx out of line Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 17/23] target-sparc: Tidy Tcc Richard Henderson
2012-10-05 23:55 ` Richard Henderson [this message]
2012-10-05 23:55 ` [Qemu-devel] [PATCH 19/23] target-sparc: Use movcond in mulscc Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 20/23] target-sparc: Use movcond for FMOV*R Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 21/23] target-sparc: Cleanup "global" temporary allocation Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 22/23] target-sparc: Fall through from not-taken trap Richard Henderson
2012-10-05 23:55 ` [Qemu-devel] [PATCH 23/23] target-sparc: Optimize conditionals using SUBCC Richard Henderson
2012-10-07 18:48   ` Blue Swirl
2012-10-07 19:16     ` Richard Henderson
2012-10-07 22:40   ` Aurelien Jarno
2012-10-07 18:44 ` [Qemu-devel] [PATCH 00/23] target-sparc comparison improvements Blue Swirl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1349481310-9237-19-git-send-email-rth@twiddle.net \
    --to=rth@twiddle.net \
    --cc=blauwirbel@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.