diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 199b653689b159b0f0784f424ed89d303de1e0ce..1d9c27c08376db57544716ebe661a14e81a53c41 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 81e4a4153d8009d037e9e778cf36fbf37f0660dc..8799648cc26e831e8d3e9973891325e7cb527e6d 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 "";
 })