diff mbox

RFA; MN10300: Fix AM33 clzsi2 pattern

Message ID m34o3eb9za.fsf@redhat.com
State New
Headers show

Commit Message

Nick Clifton June 25, 2011, 8:18 a.m. UTC
Hi Alex, Hi Jeff, Hi Richard,

  The clzsi2/bsch patterns in the MN10300 backend do not work.  There
  are two problems - firstly the starting bit-search position for the
  BSCH instruction is not set.  Secondly the BSCH instruction returns
  the bit position of the highest set bit, not the number of leading
  zeros.

  The attached patch fixes both of these problems and shaves about 200
  unexpected failures off the gcc testsuite for the AM33 or AM33_2
  multilibs.

  OK to apply ?

Cheers
  Nick

gcc/ChangeLog
2011-06-25  Nick Clifton  <nickc@redhat.com>

	* config/mn10300/mn10300.md (clzsi2): Remove unused const_int 0.
	(bsch): Remove unused second operand.
        Initialise bit search starting position.
        Convert	located bit position into a zero count.

Comments

Richard Henderson June 25, 2011, 5:01 p.m. UTC | #1
On 06/25/2011 01:18 AM, Nick Clifton wrote:
> Hi Alex, Hi Jeff, Hi Richard,
> 
>   The clzsi2/bsch patterns in the MN10300 backend do not work.  There
>   are two problems - firstly the starting bit-search position for the
>   BSCH instruction is not set. 

Yes it is.  What do you think that "unused" second operand does?


> Secondly the BSCH instruction returns
>   the bit position of the highest set bit, not the number of leading
>   zeros.

Ah, I do see that.  I recommend you put the xor in the clz expander
rather than cluttering up the "bsch" pattern.


r~
diff mbox

Patch

Index: gcc/config/mn10300/mn10300.md
===================================================================
--- gcc/config/mn10300/mn10300.md	(revision 175370)
+++ gcc/config/mn10300/mn10300.md	(working copy)
@@ -1812,21 +1812,25 @@ 
 ;; ----------------------------------------------------------------------
 
 (define_expand "clzsi2"
-  [(parallel [(set (match_operand:SI 0 "register_operand" "")
-		   (unspec:SI [(match_operand:SI 1 "register_operand" "")
-			       (const_int 0)] UNSPEC_BSCH))
+  [(parallel [(set (match_operand:SI 0 "register_operand")
+		   (unspec:SI [(match_operand:SI 1 "register_operand")]
+			       UNSPEC_BSCH))
 	      (clobber (reg:CC CC_REG))])]
   "TARGET_AM33"
 )
 
+;; 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 an xor instead since
+;; we know that the top 27 bits are clear.
 (define_insn "*bsch"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
-		    (match_operand:SI 2 "nonmemory_operand" "0")]
+  [(set (match_operand:SI 0 "register_operand" "=&r")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
 		   UNSPEC_BSCH))
    (clobber (reg:CC CC_REG))]
   "TARGET_AM33"
-  "bsch %1,%0"
+  "clr %0 ; bsch %1, %0; xor 31, %0"
 )
 
 ;; ----------------------------------------------------------------------