[PATCH] ffsdi2, clzdi2 and ctzdi2 for x86_64

Jakub Jelinek jakub@redhat.com
Wed Jun 23 19:30:00 GMT 2004


Hi!

I have noticed these are missing, so say __builtin_clz () is
optimized on x86_64 while __builtin_clzl () results in library call,
although the hardware can handle both SImode and DImode.
Ok to commit?

2004-06-23  Jakub Jelinek  <jakub@redhat.com>

	* config/i386/i386.md (ffsdi2, clzdi2): New expanders.
	(ffs_rex64): New splitter.
	(ffsdi_1, ctzdi2, bsr_rex64): New instructions.

--- gcc/config/i386/i386.md.jj	2004-06-18 15:54:39.000000000 +0200
+++ gcc/config/i386/i386.md	2004-06-23 15:55:34.234690425 +0200
@@ -13995,6 +13995,44 @@
   "bsf{l}\t{%1, %0|%0, %1}"
   [(set_attr "prefix_0f" "1")])
 
+(define_expand "ffsdi2"
+  [(parallel
+     [(set (match_operand:DI 0 "register_operand" "") 
+	   (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
+      (clobber (match_scratch:DI 2 ""))
+      (clobber (reg:CC 17))])]
+  "TARGET_64BIT && TARGET_CMOVE"
+  "")
+
+(define_insn_and_split "*ffs_rex64"
+  [(set (match_operand:DI 0 "register_operand" "=r") 
+	(ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
+   (clobber (match_scratch:DI 2 "=&r"))
+   (clobber (reg:CC 17))]
+  "TARGET_64BIT && TARGET_CMOVE"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 2) (const_int -1))
+   (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
+	      (set (match_dup 0) (ctz:DI (match_dup 1)))])
+   (set (match_dup 0) (if_then_else:DI
+			(eq (reg:CCZ 17) (const_int 0))
+			(match_dup 2)
+			(match_dup 0)))
+   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
+	      (clobber (reg:CC 17))])]
+  "")
+
+(define_insn "*ffsdi_1"
+  [(set (reg:CCZ 17)
+	(compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
+		     (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=r")
+	(ctz:DI (match_dup 1)))]
+  "TARGET_64BIT"
+  "bsf{q}\t{%1, %0|%0, %1}"
+  [(set_attr "prefix_0f" "1")])
+
 (define_insn "ctzsi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
@@ -14003,6 +14041,14 @@
   "bsf{l}\t{%1, %0|%0, %1}"
   [(set_attr "prefix_0f" "1")])
 
+(define_insn "ctzdi2"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
+   (clobber (reg:CC 17))]
+  "TARGET_64BIT"
+  "bsf{q}\t{%1, %0|%0, %1}"
+  [(set_attr "prefix_0f" "1")])
+
 (define_expand "clzsi2"
   [(parallel
      [(set (match_operand:SI 0 "register_operand" "")
@@ -14023,6 +14069,27 @@
   ""
   "bsr{l}\t{%1, %0|%0, %1}"
   [(set_attr "prefix_0f" "1")])
+
+(define_expand "clzdi2"
+  [(parallel
+     [(set (match_operand:DI 0 "register_operand" "")
+	   (minus:DI (const_int 63)
+		     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
+      (clobber (reg:CC 17))])
+   (parallel
+     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
+      (clobber (reg:CC 17))])]
+  "TARGET_64BIT"
+  "")
+
+(define_insn "*bsr_rex64"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(minus:DI (const_int 63)
+		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
+   (clobber (reg:CC 17))]
+  "TARGET_64BIT"
+  "bsr{q}\t{%1, %0|%0, %1}"
+  [(set_attr "prefix_0f" "1")])
 
 ;; Thread-local storage patterns for ELF.
 ;;

	Jakub



More information about the Gcc-patches mailing list