qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [6198] CRIS: Slight performance improvement for flag evaluation.
Date: Wed, 07 Jan 2009 12:25:15 +0000	[thread overview]
Message-ID: <E1LKXTH-00051p-TS@cvs.savannah.gnu.org> (raw)

Revision: 6198
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6198
Author:   edgar_igl
Date:     2009-01-07 12:25:15 +0000 (Wed, 07 Jan 2009)

Log Message:
-----------
CRIS: Slight performance improvement for flag evaluation.

Translate sub and cmp ops separately when evaluating flags to avoid checking
for them at runtime.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>

Modified Paths:
--------------
    trunk/target-cris/helper.h
    trunk/target-cris/op_helper.c
    trunk/target-cris/translate.c

Modified: trunk/target-cris/helper.h
===================================================================
--- trunk/target-cris/helper.h	2009-01-07 12:19:50 UTC (rev 6197)
+++ trunk/target-cris/helper.h	2009-01-07 12:25:15 UTC (rev 6198)
@@ -14,6 +14,7 @@
 DEF_HELPER_0(evaluate_flags_mulu, void)
 DEF_HELPER_0(evaluate_flags_mcp, void)
 DEF_HELPER_0(evaluate_flags_alu_4, void)
+DEF_HELPER_0(evaluate_flags_sub_4, void)
 DEF_HELPER_0(evaluate_flags_move_4, void)
 DEF_HELPER_0(evaluate_flags_move_2, void)
 DEF_HELPER_0(evaluate_flags, void)

Modified: trunk/target-cris/op_helper.c
===================================================================
--- trunk/target-cris/op_helper.c	2009-01-07 12:19:50 UTC (rev 6197)
+++ trunk/target-cris/op_helper.c	2009-01-07 12:25:15 UTC (rev 6198)
@@ -245,17 +245,19 @@
 
 static void evaluate_flags_writeback(uint32_t flags)
 {
-	int x;
+	unsigned int x, z, mask;
 
 	/* Extended arithmetics, leave the z flag alone.  */
 	x = env->cc_x;
-	if ((x || env->cc_op == CC_OP_ADDC)
-	    && flags & Z_FLAG)
-		env->cc_mask &= ~Z_FLAG;
+	mask = env->cc_mask | X_FLAG;
+        if (x) {
+		z = flags & Z_FLAG;
+		mask = mask & ~z;
+	}
+	flags &= mask;
 
 	/* all insn clear the x-flag except setf or clrf.  */
-	env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG);
-	flags &= env->cc_mask;
+	env->pregs[PR_CCS] &= ~mask;
 	env->pregs[PR_CCS] |= flags;
 }
 
@@ -323,33 +325,25 @@
 	uint32_t res;
 	uint32_t flags = 0;
 
-	src = env->cc_src;
-	dst = env->cc_dest;
+	src = env->cc_src & 0x80000000;
+	dst = env->cc_dest & 0x80000000;
 	res = env->cc_result;
 
 	if ((res & 0x80000000L) != 0L)
 	{
 		flags |= N_FLAG;
-		if (((src & 0x80000000L) == 0L)
-		    && ((dst & 0x80000000L) == 0L))
-		{
+		if (!src && !dst)
 			flags |= V_FLAG;
-		}
-		else if (((src & 0x80000000L) != 0L) &&
-			 ((dst & 0x80000000L) != 0L))
-		{
+		else if (src & dst)
 			flags |= R_FLAG;
-		}
 	}
 	else
 	{
 		if (res == 0L)
 			flags |= Z_FLAG;
-		if (((src & 0x80000000L) != 0L)
-		    && ((dst & 0x80000000L) != 0L))
+		if (src & dst) 
 			flags |= V_FLAG;
-		if ((dst & 0x80000000L) != 0L
-		    || (src & 0x80000000L) != 0L)
+		if (dst | src) 
 			flags |= R_FLAG;
 	}
 
@@ -363,56 +357,61 @@
 	uint32_t res;
 	uint32_t flags = 0;
 
-	src = env->cc_src;
-	dst = env->cc_dest;
+	src = env->cc_src & 0x80000000;
+	dst = env->cc_dest & 0x80000000;
+	res = env->cc_result;
 
-	/* Reconstruct the result.  */
-	switch (env->cc_op)
+	if ((res & 0x80000000L) != 0L)
 	{
-		case CC_OP_SUB:
-			res = dst - src;
-			break;
-		case CC_OP_ADD:
-			res = dst + src;
-			break;
-		default:
-			res = env->cc_result;
-			break;
+		flags |= N_FLAG;
+		if (!src && !dst)
+			flags |= V_FLAG;
+		else if (src & dst)
+			flags |= C_FLAG;
 	}
+	else
+	{
+		if (res == 0L)
+			flags |= Z_FLAG;
+		if (src & dst) 
+			flags |= V_FLAG;
+		if (dst | src) 
+			flags |= C_FLAG;
+	}
 
-	if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
-		src = ~src;
+	evaluate_flags_writeback(flags);
+}
 
+void  helper_evaluate_flags_sub_4(void)
+{
+	uint32_t src;
+	uint32_t dst;
+	uint32_t res;
+	uint32_t flags = 0;
+
+	src = (~env->cc_src) & 0x80000000;
+	dst = env->cc_dest & 0x80000000;
+	res = env->cc_result;
+
 	if ((res & 0x80000000L) != 0L)
 	{
 		flags |= N_FLAG;
-		if (((src & 0x80000000L) == 0L)
-		    && ((dst & 0x80000000L) == 0L))
-		{
+		if (!src && !dst)
 			flags |= V_FLAG;
-		}
-		else if (((src & 0x80000000L) != 0L) &&
-			 ((dst & 0x80000000L) != 0L))
-		{
+		else if (src & dst)
 			flags |= C_FLAG;
-		}
 	}
 	else
 	{
 		if (res == 0L)
 			flags |= Z_FLAG;
-		if (((src & 0x80000000L) != 0L)
-		    && ((dst & 0x80000000L) != 0L))
+		if (src & dst) 
 			flags |= V_FLAG;
-		if ((dst & 0x80000000L) != 0L
-		    || (src & 0x80000000L) != 0L)
+		if (dst | src) 
 			flags |= C_FLAG;
 	}
 
-	if (env->cc_op == CC_OP_SUB
-	    || env->cc_op == CC_OP_CMP) {
-		flags ^= C_FLAG;
-	}
+	flags ^= C_FLAG;
 	evaluate_flags_writeback(flags);
 }
 
@@ -607,6 +606,13 @@
 		case CC_OP_FLAGS:
 			/* live.  */
 			break;
+		case CC_OP_SUB:
+		case CC_OP_CMP:
+			if (env->cc_size == 4)
+				helper_evaluate_flags_sub_4();
+			else
+				helper_evaluate_flags();
+			break;
 		default:
 		{
 			switch (env->cc_size)

Modified: trunk/target-cris/translate.c
===================================================================
--- trunk/target-cris/translate.c	2009-01-07 12:19:50 UTC (rev 6197)
+++ trunk/target-cris/translate.c	2009-01-07 12:25:15 UTC (rev 6198)
@@ -728,8 +728,15 @@
 			case CC_OP_FLAGS:
 				/* live.  */
 				break;
+			case CC_OP_SUB:
+			case CC_OP_CMP:
+				if (dc->cc_size == 4)
+					gen_helper_evaluate_flags_sub_4();
+				else
+					gen_helper_evaluate_flags();
+
+				break;
 			default:
-			{
 				switch (dc->cc_size)
 				{
 					case 4:
@@ -739,7 +746,6 @@
 						gen_helper_evaluate_flags();
 						break;
 				}
-			}
 			break;
 		}
 		if (dc->flagx_known) {
@@ -821,13 +827,8 @@
 /* Update cc after executing ALU op. needs the result.  */
 static inline void cris_update_result(DisasContext *dc, TCGv res)
 {
-	if (dc->update_cc) {
-		if (dc->cc_size == 4 && 
-		    (dc->cc_op == CC_OP_SUB
-		     || dc->cc_op == CC_OP_ADD))
-			return;
+	if (dc->update_cc)
 		tcg_gen_mov_tl(cc_result, res);
-	}
 }
 
 /* Returns one if the write back stage should execute.  */
@@ -1890,6 +1891,10 @@
 	DIS(fprintf (logfile, "addc $r%u, $r%u\n",
 		    dc->op1, dc->op2));
 	cris_evaluate_flags(dc);
+	/* Set for this insn.  */
+	dc->flagx_known = 1;
+	dc->flags_x = X_FLAG;
+
 	cris_cc_mask(dc, CC_MASK_NZVC);
 	cris_alu(dc, CC_OP_ADDC,
 		 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
@@ -2615,6 +2620,11 @@
 		    dc->op2));
 
 	cris_evaluate_flags(dc);
+
+	/* Set for this insn.  */
+	dc->flagx_known = 1;
+	dc->flags_x = X_FLAG;
+
 	cris_alu_m_alloc_temps(t);
 	insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
 	cris_cc_mask(dc, CC_MASK_NZVC);

                 reply	other threads:[~2009-01-07 12:25 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=E1LKXTH-00051p-TS@cvs.savannah.gnu.org \
    --to=edgar.iglesias@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).