From bebd619ecc3ce2fc8e82efc2830cf9de5c9d2cdd Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Mon, 27 Jun 2011 15:52:26 +0000
Subject: [PATCH] mn10300.md (clzsi2): Use XOR after BSCH to convert bit
 position of highest bit set into a count of...

	* config/mn10300/mn10300.md (clzsi2): Use XOR after BSCH to
	convert bit position of highest bit set into a count of the high
	zero bits.

From-SVN: r175536
---
 gcc/ChangeLog                 |  6 ++++++
 gcc/config/mn10300/mn10300.md | 22 ++++++++++++++++++----
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 199b653689b1..1d9c27c08376 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-06-27  Nick Clifton  <nickc@redhat.com>
+
+	* config/mn10300/mn10300.md (clzsi2): Use XOR after BSCH to
+	convert bit position of highest bit set into a count of the high
+	zero bits.
+
 2011-06-27  Eric Botcazou  <ebotcazou@adacore.com>
 
 	* dwarf2out.c (TYPE_DECL_IS_STUB): Extend mechanism to all types.
diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md
index 81e4a4153d80..8799648cc26e 100644
--- a/gcc/config/mn10300/mn10300.md
+++ b/gcc/config/mn10300/mn10300.md
@@ -1811,10 +1811,24 @@
 ;; MISCELANEOUS
 ;; ----------------------------------------------------------------------
 
+;; Note the use of the (const_int 0) when generating the insn that matches
+;; the bsch pattern.  This ensures that the destination register is
+;; initialised with 0 which will make the BSCH instruction set searching
+;; at bit 31.
+;;
+;; The XOR in the instruction sequence below is there because the BSCH
+;; instruction returns the bit number of the highest set bit and we want
+;; the number of zero bits above that bit.  The AM33 does not have a
+;; reverse subtraction instruction, but we can use a simple xor instead
+;; since we know that the top 27 bits are clear.
 (define_expand "clzsi2"
-  [(parallel [(set (match_operand:SI 0 "register_operand" "")
-		   (unspec:SI [(match_operand:SI 1 "register_operand" "")
+  [(parallel [(set (match_operand:SI 0 "register_operand")
+		   (unspec:SI [(match_operand:SI 1 "register_operand")
 			       (const_int 0)] UNSPEC_BSCH))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0)
+		   (xor:SI (match_dup 0)
+			   (const_int 31)))
 	      (clobber (reg:CC CC_REG))])]
   "TARGET_AM33"
 )
@@ -1826,7 +1840,7 @@
 		   UNSPEC_BSCH))
    (clobber (reg:CC CC_REG))]
   "TARGET_AM33"
-  "bsch %1,%0"
+  "bsch %1, %0"
 )
 
 ;; ----------------------------------------------------------------------
@@ -2034,7 +2048,7 @@
 {
   /* The RETF insn is up to 3 cycles faster than RET.  */
   fputs ((mn10300_can_use_retf_insn () ? "\tretf " : "\tret "), asm_out_file);
-  mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
+  mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs (NULL));
   fprintf (asm_out_file, ",%d\n", (int) INTVAL (operands[0]));
   return "";
 })
-- 
GitLab