Linux MIPS Architecture development
 help / color / mirror / Atom feed
From: David Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org, ralf@linux-mips.org
Cc: David Daney <ddaney@caviumnetworks.com>
Subject: [PATCH 2/2] MIPS: Don't branch to eret in TLB refill.
Date: Wed, 13 May 2009 13:48:37 -0700	[thread overview]
Message-ID: <1242247717-21324-2-git-send-email-ddaney@caviumnetworks.com> (raw)
In-Reply-To: <4A0B31C6.9050804@caviumnetworks.com>

If the TLB refill handler is too big and needs to be split, there is
no need to branch around the split if the branch target would be an
eret.  Since the eret returns from the handler, control flow never
passes it.  A branch to an eret is equivalent to the eret itself.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/mips/mm/tlbex.c |   66 ++++++++++++++++++++++++++++++-------------------
 1 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index d99ed78..0a88383 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -664,6 +664,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
 	struct uasm_reloc *r = relocs;
 	u32 *f;
 	unsigned int final_len;
+	int split_on_eret;
 
 	memset(tlb_handler, 0, sizeof(tlb_handler));
 	memset(labels, 0, sizeof(labels));
@@ -693,6 +694,12 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
 	build_tlb_write_entry(&p, &l, &r, tlb_random);
 	uasm_l_leave(&l, p);
 	uasm_i_eret(&p); /* return from trap */
+	/*
+	 * Check to see if the eret was the last instruction before
+	 * the split.  If it was, there will be no need to branch
+	 * around the split, because we are returning.
+	 */
+	split_on_eret = (p - tlb_handler == MIPS64_REFILL_INSNS);
 
 #ifdef CONFIG_64BIT
 	build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
@@ -732,36 +739,43 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
 		uasm_copy_handler(relocs, labels, tlb_handler, p, f);
 		final_len = p - tlb_handler;
 	} else {
-		/*
-		 * Split two instructions before the end.  One for the
-		 * branch and one for the instruction in the delay
-		 * slot.
-		 */
-		u32 *split = tlb_handler + MIPS64_REFILL_INSNS - 2;
-
-		/*
-		 * Find the split point.  If the branch would fall in
-		 * a delay slot, we must back up an additional
-		 * instruction so that it is no longer in a delay
-		 * slot.
-		 */
-		if (uasm_insn_has_bdelay(relocs, split - 1))
-			split--;
-
+		u32 *split;
+		if (split_on_eret) {
+			split = tlb_handler + MIPS64_REFILL_INSNS;
+		} else {
+			/*
+			 * Split two instructions before the end.  One
+			 * for the branch and one for the instruction
+			 * in the delay slot.
+			 */
+			u32 *split = tlb_handler + MIPS64_REFILL_INSNS - 2;
+
+			/*
+			 * Find the split point.  If the branch would
+			 * fall in a delay slot, we must back up an
+			 * additional instruction so that it is no
+			 * longer in a delay slot.
+			 */
+			if (uasm_insn_has_bdelay(relocs, split - 1))
+				split--;
+		}
 		/* Copy first part of the handler. */
 		uasm_copy_handler(relocs, labels, tlb_handler, split, f);
 		f += split - tlb_handler;
 
-		/* Insert branch. */
-		uasm_l_split(&l, final_handler);
-		uasm_il_b(&f, &r, label_split);
-		if (uasm_insn_has_bdelay(relocs, split))
-			uasm_i_nop(&f);
-		else {
-			uasm_copy_handler(relocs, labels, split, split + 1, f);
-			uasm_move_labels(labels, f, f + 1, -1);
-			f++;
-			split++;
+		if (!split_on_eret) {
+			/* Insert branch. */
+			uasm_l_split(&l, final_handler);
+			uasm_il_b(&f, &r, label_split);
+			if (uasm_insn_has_bdelay(relocs, split))
+				uasm_i_nop(&f);
+			else {
+				uasm_copy_handler(relocs, labels,
+						  split, split + 1, f);
+				uasm_move_labels(labels, f, f + 1, -1);
+				f++;
+				split++;
+			}
 		}
 
 		/* Copy the rest of the handler. */
-- 
1.6.0.6

  parent reply	other threads:[~2009-05-13 20:49 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-13 20:47 [PATCH 0/2] MIPS: Cleanup and optimize tlbex.c David Daney
2009-05-13 20:48 ` [PATCH 1/2] MIPS: Replace some magic numbers with symbolic values in tlbex.c David Daney
2009-05-13 21:34   ` Paul Gortmaker
2009-05-13 22:20   ` [PATCH 1/2] MIPS: Replace some magic numbers with symbolic values in tlbex.c (v2) David Daney
2009-05-13 20:48 ` David Daney [this message]
2009-05-13 22:15   ` [PATCH 2/2] " David Daney
2009-05-13 22:17     ` David Daney

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=1242247717-21324-2-git-send-email-ddaney@caviumnetworks.com \
    --to=ddaney@caviumnetworks.com \
    --cc=linux-mips@linux-mips.org \
    --cc=ralf@linux-mips.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