Patchwork [i386] : Macroize block operations

login
register
mail settings
Submitter Uros Bizjak
Date Oct. 11, 2010, 8:34 p.m.
Message ID <AANLkTikDO5Sm0vwHeG9VO=MudCMNn1jC--cMOtEkThEz@mail.gmail.com>
Download mbox | patch
Permalink /patch/67479/
State New
Headers show

Comments

Uros Bizjak - Oct. 11, 2010, 8:34 p.m.
Hello!

2010-10-11  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/i386.md (movmem<mode>): Macroize expander from
	movmem{si,di} using SWI48 mode iterator.
	(*strmovsi_1): Macroize insn pattern from *strmovsi_1 and
	*strmovsi_rex_1 using P mode iterator.
	(*strmovhi_1): Ditto from *strmovhi_1 and *strmovhi_rex_1.
	(*strmovqi_1): Ditto from *strmovqi_1 and *strmovqi_rex_1.
	(*rep_movsi): Ditto from *rep_movsi and *rep_movsi_rex64.
	(*rep_movqi): Ditto from *rep_movqi and *rep_movqi_rex64.
	(setmem<mode>): Macroize expander from setmem{si,di} using
	SWI48 mode iterator.
	(*strsetsi_1): Macroize insn pattern from *strsetsi_1 and
	*strsetsi_rex_1 using P mode iterator.
	(*strsethi_1): Ditto from *strsethi_1 and *strsethi_rex_1.
	(*strsetqi_1): Ditto from *strsetqi_1 and *strsetqi_rex_1.
	(*rep_stossi): Ditto from *rep_stossi and *rep_stossi_rex64.
	(*rep_stosqi): Ditto from *rep_stosqi and *rep_stosqi_rex64.
	(*cmpstrnqi_nz_1): Ditto from *cmpstrnqi_nz_1 and *cmpstrnqi_nz_rex_1.
	(*cmpstrnqi_1): Ditto from *cmpstrnqi_1 and *cmpstrnqi_rex_1.
	(strlen<mode>): Macroize expander from strlen{si,di} using SWI48x
	mode iterator.
	(*strlenqi_1): Macroize insn pattern from *strlenqi_1 and
	*strlenqi_rex_1 using P mode iterator.

Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN.

Uros.

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 165314)
+++ config/i386/i386.md	(working copy)
@@ -15189,11 +15189,11 @@ 
    (set_attr "length_immediate" "0")
    (set_attr "modrm" "0")])
 
-(define_expand "movmemsi"
+(define_expand "movmem<mode>"
   [(use (match_operand:BLK 0 "memory_operand" ""))
    (use (match_operand:BLK 1 "memory_operand" ""))
-   (use (match_operand:SI 2 "nonmemory_operand" ""))
-   (use (match_operand:SI 3 "const_int_operand" ""))
+   (use (match_operand:SWI48 2 "nonmemory_operand" ""))
+   (use (match_operand:SWI48 3 "const_int_operand" ""))
    (use (match_operand:SI 4 "const_int_operand" ""))
    (use (match_operand:SI 5 "const_int_operand" ""))]
   ""
@@ -15205,22 +15205,6 @@ 
    FAIL;
 })
 
-(define_expand "movmemdi"
-  [(use (match_operand:BLK 0 "memory_operand" ""))
-   (use (match_operand:BLK 1 "memory_operand" ""))
-   (use (match_operand:DI 2 "nonmemory_operand" ""))
-   (use (match_operand:DI 3 "const_int_operand" ""))
-   (use (match_operand:SI 4 "const_int_operand" ""))
-   (use (match_operand:SI 5 "const_int_operand" ""))]
-  "TARGET_64BIT"
-{
- if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
-			 operands[4], operands[5]))
-   DONE;
- else
-   FAIL;
-})
-
 ;; Most CPUs don't like single string operations
 ;; Handle this case here to simplify previous expander.
 
@@ -15275,100 +15259,59 @@ 
   "TARGET_64BIT"
   "movsq"
   [(set_attr "type" "str")
-   (set_attr "mode" "DI")
-   (set_attr "memory" "both")])
+   (set_attr "memory" "both")
+   (set_attr "mode" "DI")])
 
 (define_insn "*strmovsi_1"
-  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
-	(mem:SI (match_operand:SI 3 "register_operand" "1")))
-   (set (match_operand:SI 0 "register_operand" "=D")
-	(plus:SI (match_dup 2)
-		 (const_int 4)))
-   (set (match_operand:SI 1 "register_operand" "=S")
-	(plus:SI (match_dup 3)
-		 (const_int 4)))]
-  "!TARGET_64BIT"
+  [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
+	(mem:SI (match_operand:P 3 "register_operand" "1")))
+   (set (match_operand:P 0 "register_operand" "=D")
+	(plus:P (match_dup 2)
+		(const_int 4)))
+   (set (match_operand:P 1 "register_operand" "=S")
+	(plus:P (match_dup 3)
+		(const_int 4)))]
+  ""
   "movs{l|d}"
   [(set_attr "type" "str")
-   (set_attr "mode" "SI")
-   (set_attr "memory" "both")])
+   (set_attr "memory" "both")
+   (set_attr "mode" "SI")])
 
-(define_insn "*strmovsi_rex_1"
-  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
-	(mem:SI (match_operand:DI 3 "register_operand" "1")))
-   (set (match_operand:DI 0 "register_operand" "=D")
-	(plus:DI (match_dup 2)
-		 (const_int 4)))
-   (set (match_operand:DI 1 "register_operand" "=S")
-	(plus:DI (match_dup 3)
-		 (const_int 4)))]
-  "TARGET_64BIT"
-  "movs{l|d}"
-  [(set_attr "type" "str")
-   (set_attr "mode" "SI")
-   (set_attr "memory" "both")])
-
 (define_insn "*strmovhi_1"
-  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
-	(mem:HI (match_operand:SI 3 "register_operand" "1")))
-   (set (match_operand:SI 0 "register_operand" "=D")
-	(plus:SI (match_dup 2)
-		 (const_int 2)))
-   (set (match_operand:SI 1 "register_operand" "=S")
-	(plus:SI (match_dup 3)
-		 (const_int 2)))]
-  "!TARGET_64BIT"
+  [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
+	(mem:HI (match_operand:P 3 "register_operand" "1")))
+   (set (match_operand:P 0 "register_operand" "=D")
+	(plus:P (match_dup 2)
+		(const_int 2)))
+   (set (match_operand:P 1 "register_operand" "=S")
+	(plus:P (match_dup 3)
+		(const_int 2)))]
+  ""
   "movsw"
   [(set_attr "type" "str")
    (set_attr "memory" "both")
    (set_attr "mode" "HI")])
 
-(define_insn "*strmovhi_rex_1"
-  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
-	(mem:HI (match_operand:DI 3 "register_operand" "1")))
-   (set (match_operand:DI 0 "register_operand" "=D")
-	(plus:DI (match_dup 2)
-		 (const_int 2)))
-   (set (match_operand:DI 1 "register_operand" "=S")
-	(plus:DI (match_dup 3)
-		 (const_int 2)))]
-  "TARGET_64BIT"
-  "movsw"
-  [(set_attr "type" "str")
-   (set_attr "memory" "both")
-   (set_attr "mode" "HI")])
-
 (define_insn "*strmovqi_1"
-  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
-	(mem:QI (match_operand:SI 3 "register_operand" "1")))
-   (set (match_operand:SI 0 "register_operand" "=D")
-	(plus:SI (match_dup 2)
-		 (const_int 1)))
-   (set (match_operand:SI 1 "register_operand" "=S")
-	(plus:SI (match_dup 3)
-		 (const_int 1)))]
-  "!TARGET_64BIT"
+  [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
+	(mem:QI (match_operand:P 3 "register_operand" "1")))
+   (set (match_operand:P 0 "register_operand" "=D")
+	(plus:P (match_dup 2)
+		(const_int 1)))
+   (set (match_operand:P 1 "register_operand" "=S")
+	(plus:P (match_dup 3)
+		(const_int 1)))]
+  ""
   "movsb"
   [(set_attr "type" "str")
    (set_attr "memory" "both")
+   (set (attr "prefix_rex")
+	(if_then_else
+	  (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+	  (const_string "0")
+	  (const_string "*")))
    (set_attr "mode" "QI")])
 
-(define_insn "*strmovqi_rex_1"
-  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
-	(mem:QI (match_operand:DI 3 "register_operand" "1")))
-   (set (match_operand:DI 0 "register_operand" "=D")
-	(plus:DI (match_dup 2)
-		 (const_int 1)))
-   (set (match_operand:DI 1 "register_operand" "=S")
-	(plus:DI (match_dup 3)
-		 (const_int 1)))]
-  "TARGET_64BIT"
-  "movsb"
-  [(set_attr "type" "str")
-   (set_attr "memory" "both")
-   (set_attr "prefix_rex" "0")
-   (set_attr "mode" "QI")])
-
 (define_expand "rep_mov"
   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
 	      (set (match_operand 0 "register_operand" "")
@@ -15401,80 +15344,44 @@ 
    (set_attr "mode" "DI")])
 
 (define_insn "*rep_movsi"
-  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
-   (set (match_operand:SI 0 "register_operand" "=D")
-        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
-			    (const_int 2))
-		 (match_operand:SI 3 "register_operand" "0")))
-   (set (match_operand:SI 1 "register_operand" "=S")
-        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
-		 (match_operand:SI 4 "register_operand" "1")))
+  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
+   (set (match_operand:P 0 "register_operand" "=D")
+        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
+			  (const_int 2))
+		 (match_operand:P 3 "register_operand" "0")))
+   (set (match_operand:P 1 "register_operand" "=S")
+        (plus:P (ashift:P (match_dup 5) (const_int 2))
+		(match_operand:P 4 "register_operand" "1")))
    (set (mem:BLK (match_dup 3))
 	(mem:BLK (match_dup 4)))
    (use (match_dup 5))]
-  "!TARGET_64BIT"
+  ""
   "rep{%;} movs{l|d}"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "both")
    (set_attr "mode" "SI")])
 
-(define_insn "*rep_movsi_rex64"
-  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
-   (set (match_operand:DI 0 "register_operand" "=D")
-        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
-			    (const_int 2))
-		 (match_operand:DI 3 "register_operand" "0")))
-   (set (match_operand:DI 1 "register_operand" "=S")
-        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
-		 (match_operand:DI 4 "register_operand" "1")))
-   (set (mem:BLK (match_dup 3))
-	(mem:BLK (match_dup 4)))
-   (use (match_dup 5))]
-  "TARGET_64BIT"
-  "rep{%;} movs{l|d}"
-  [(set_attr "type" "str")
-   (set_attr "prefix_rep" "1")
-   (set_attr "memory" "both")
-   (set_attr "mode" "SI")])
-
 (define_insn "*rep_movqi"
-  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
-   (set (match_operand:SI 0 "register_operand" "=D")
-        (plus:SI (match_operand:SI 3 "register_operand" "0")
-		 (match_operand:SI 5 "register_operand" "2")))
-   (set (match_operand:SI 1 "register_operand" "=S")
-        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
+  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
+   (set (match_operand:P 0 "register_operand" "=D")
+        (plus:P (match_operand:P 3 "register_operand" "0")
+		(match_operand:P 5 "register_operand" "2")))
+   (set (match_operand:P 1 "register_operand" "=S")
+        (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
    (set (mem:BLK (match_dup 3))
 	(mem:BLK (match_dup 4)))
    (use (match_dup 5))]
-  "!TARGET_64BIT"
+  ""
   "rep{%;} movsb"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "both")
-   (set_attr "mode" "SI")])
+   (set_attr "mode" "QI")])
 
-(define_insn "*rep_movqi_rex64"
-  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
-   (set (match_operand:DI 0 "register_operand" "=D")
-        (plus:DI (match_operand:DI 3 "register_operand" "0")
-		 (match_operand:DI 5 "register_operand" "2")))
-   (set (match_operand:DI 1 "register_operand" "=S")
-        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
-   (set (mem:BLK (match_dup 3))
-	(mem:BLK (match_dup 4)))
-   (use (match_dup 5))]
-  "TARGET_64BIT"
-  "rep{%;} movsb"
-  [(set_attr "type" "str")
-   (set_attr "prefix_rep" "1")
-   (set_attr "memory" "both")
-   (set_attr "mode" "SI")])
-
-(define_expand "setmemsi"
+(define_expand "setmem<mode>"
    [(use (match_operand:BLK 0 "memory_operand" ""))
-    (use (match_operand:SI 1 "nonmemory_operand" ""))
+    (use (match_operand:SWI48 1 "nonmemory_operand" ""))
     (use (match_operand 2 "const_int_operand" ""))
     (use (match_operand 3 "const_int_operand" ""))
     (use (match_operand:SI 4 "const_int_operand" ""))
@@ -15489,23 +15396,6 @@ 
    FAIL;
 })
 
-(define_expand "setmemdi"
-   [(use (match_operand:BLK 0 "memory_operand" ""))
-    (use (match_operand:DI 1 "nonmemory_operand" ""))
-    (use (match_operand 2 "const_int_operand" ""))
-    (use (match_operand 3 "const_int_operand" ""))
-    (use (match_operand 4 "const_int_operand" ""))
-    (use (match_operand 5 "const_int_operand" ""))]
-  "TARGET_64BIT"
-{
- if (ix86_expand_setmem (operands[0], operands[1],
-			 operands[2], operands[3],
-			 operands[4], operands[5]))
-   DONE;
- else
-   FAIL;
-})
-
 ;; Most CPUs don't like single string operations
 ;; Handle this case here to simplify previous expander.
 
@@ -15554,78 +15444,46 @@ 
    (set_attr "mode" "DI")])
 
 (define_insn "*strsetsi_1"
-  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
+  [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
 	(match_operand:SI 2 "register_operand" "a"))
-   (set (match_operand:SI 0 "register_operand" "=D")
-	(plus:SI (match_dup 1)
-		 (const_int 4)))]
-  "!TARGET_64BIT"
+   (set (match_operand:P 0 "register_operand" "=D")
+	(plus:P (match_dup 1)
+		(const_int 4)))]
+  ""
   "stos{l|d}"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
    (set_attr "mode" "SI")])
 
-(define_insn "*strsetsi_rex_1"
-  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
-	(match_operand:SI 2 "register_operand" "a"))
-   (set (match_operand:DI 0 "register_operand" "=D")
-	(plus:DI (match_dup 1)
-		 (const_int 4)))]
-  "TARGET_64BIT"
-  "stos{l|d}"
-  [(set_attr "type" "str")
-   (set_attr "memory" "store")
-   (set_attr "mode" "SI")])
-
 (define_insn "*strsethi_1"
-  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
+  [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
 	(match_operand:HI 2 "register_operand" "a"))
-   (set (match_operand:SI 0 "register_operand" "=D")
-	(plus:SI (match_dup 1)
-		 (const_int 2)))]
-  "!TARGET_64BIT"
+   (set (match_operand:P 0 "register_operand" "=D")
+	(plus:P (match_dup 1)
+		(const_int 2)))]
+  ""
   "stosw"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
    (set_attr "mode" "HI")])
 
-(define_insn "*strsethi_rex_1"
-  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
-	(match_operand:HI 2 "register_operand" "a"))
-   (set (match_operand:DI 0 "register_operand" "=D")
-	(plus:DI (match_dup 1)
-		 (const_int 2)))]
-  "TARGET_64BIT"
-  "stosw"
-  [(set_attr "type" "str")
-   (set_attr "memory" "store")
-   (set_attr "mode" "HI")])
-
 (define_insn "*strsetqi_1"
-  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
+  [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
 	(match_operand:QI 2 "register_operand" "a"))
-   (set (match_operand:SI 0 "register_operand" "=D")
-	(plus:SI (match_dup 1)
-		 (const_int 1)))]
-  "!TARGET_64BIT"
+   (set (match_operand:P 0 "register_operand" "=D")
+	(plus:P (match_dup 1)
+		(const_int 1)))]
+  ""
   "stosb"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
+   (set (attr "prefix_rex")
+	(if_then_else
+	  (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+	  (const_string "0")
+	  (const_string "*")))
    (set_attr "mode" "QI")])
 
-(define_insn "*strsetqi_rex_1"
-  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
-	(match_operand:QI 2 "register_operand" "a"))
-   (set (match_operand:DI 0 "register_operand" "=D")
-	(plus:DI (match_dup 1)
-		 (const_int 1)))]
-  "TARGET_64BIT"
-  "stosb"
-  [(set_attr "type" "str")
-   (set_attr "memory" "store")
-   (set_attr "prefix_rex" "0")
-   (set_attr "mode" "QI")])
-
 (define_expand "rep_stos"
   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
 	      (set (match_operand 0 "register_operand" "")
@@ -15654,72 +15512,43 @@ 
    (set_attr "mode" "DI")])
 
 (define_insn "*rep_stossi"
-  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
-   (set (match_operand:SI 0 "register_operand" "=D")
-        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
-			    (const_int 2))
-		 (match_operand:SI 3 "register_operand" "0")))
+  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
+   (set (match_operand:P 0 "register_operand" "=D")
+        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
+			  (const_int 2))
+		 (match_operand:P 3 "register_operand" "0")))
    (set (mem:BLK (match_dup 3))
 	(const_int 0))
    (use (match_operand:SI 2 "register_operand" "a"))
    (use (match_dup 4))]
-  "!TARGET_64BIT"
+  ""
   "rep{%;} stos{l|d}"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "store")
    (set_attr "mode" "SI")])
 
-(define_insn "*rep_stossi_rex64"
-  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
-   (set (match_operand:DI 0 "register_operand" "=D")
-        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
-			    (const_int 2))
-		 (match_operand:DI 3 "register_operand" "0")))
-   (set (mem:BLK (match_dup 3))
-	(const_int 0))
-   (use (match_operand:SI 2 "register_operand" "a"))
-   (use (match_dup 4))]
-  "TARGET_64BIT"
-  "rep{%;} stos{l|d}"
-  [(set_attr "type" "str")
-   (set_attr "prefix_rep" "1")
-   (set_attr "memory" "store")
-   (set_attr "mode" "SI")])
-
 (define_insn "*rep_stosqi"
-  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
-   (set (match_operand:SI 0 "register_operand" "=D")
-        (plus:SI (match_operand:SI 3 "register_operand" "0")
-		 (match_operand:SI 4 "register_operand" "1")))
+  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
+   (set (match_operand:P 0 "register_operand" "=D")
+        (plus:P (match_operand:P 3 "register_operand" "0")
+		(match_operand:P 4 "register_operand" "1")))
    (set (mem:BLK (match_dup 3))
 	(const_int 0))
    (use (match_operand:QI 2 "register_operand" "a"))
    (use (match_dup 4))]
-  "!TARGET_64BIT"
+  ""
   "rep{%;} stosb"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "store")
+   (set (attr "prefix_rex")
+	(if_then_else
+	  (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+	  (const_string "0")
+	  (const_string "*")))
    (set_attr "mode" "QI")])
 
-(define_insn "*rep_stosqi_rex64"
-  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
-   (set (match_operand:DI 0 "register_operand" "=D")
-        (plus:DI (match_operand:DI 3 "register_operand" "0")
-		 (match_operand:DI 4 "register_operand" "1")))
-   (set (mem:BLK (match_dup 3))
-	(const_int 0))
-   (use (match_operand:QI 2 "register_operand" "a"))
-   (use (match_dup 4))]
-  "TARGET_64BIT"
-  "rep{%;} stosb"
-  [(set_attr "type" "str")
-   (set_attr "prefix_rep" "1")
-   (set_attr "memory" "store")
-   (set_attr "prefix_rex" "0")
-   (set_attr "mode" "QI")])
-
 (define_expand "cmpstrnsi"
   [(set (match_operand:SI 0 "register_operand" "")
 	(compare:SI (match_operand:BLK 1 "general_operand" "")
@@ -15800,8 +15629,10 @@ 
 			     (match_dup 2)))
 	      (clobber (reg:CC FLAGS_REG))])]
   ""
-  "operands[1] = gen_reg_rtx (QImode);
-   operands[2] = gen_reg_rtx (QImode);")
+{
+  operands[1] = gen_reg_rtx (QImode);
+  operands[2] = gen_reg_rtx (QImode);
+})
 
 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
@@ -15820,35 +15651,24 @@ 
 
 (define_insn "*cmpstrnqi_nz_1"
   [(set (reg:CC FLAGS_REG)
-	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
-		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
-   (use (match_operand:SI 6 "register_operand" "2"))
+	(compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
+		    (mem:BLK (match_operand:P 5 "register_operand" "1"))))
+   (use (match_operand:P 6 "register_operand" "2"))
    (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_operand:SI 0 "register_operand" "=S"))
-   (clobber (match_operand:SI 1 "register_operand" "=D"))
-   (clobber (match_operand:SI 2 "register_operand" "=c"))]
-  "!TARGET_64BIT"
+   (clobber (match_operand:P 0 "register_operand" "=S"))
+   (clobber (match_operand:P 1 "register_operand" "=D"))
+   (clobber (match_operand:P 2 "register_operand" "=c"))]
+  ""
   "repz{%;} cmpsb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set (attr "prefix_rex")
+	(if_then_else
+	  (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+	  (const_string "0")
+	  (const_string "*")))
    (set_attr "prefix_rep" "1")])
 
-(define_insn "*cmpstrnqi_nz_rex_1"
-  [(set (reg:CC FLAGS_REG)
-	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
-		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
-   (use (match_operand:DI 6 "register_operand" "2"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_operand:DI 0 "register_operand" "=S"))
-   (clobber (match_operand:DI 1 "register_operand" "=D"))
-   (clobber (match_operand:DI 2 "register_operand" "=c"))]
-  "TARGET_64BIT"
-  "repz{%;} cmpsb"
-  [(set_attr "type" "str")
-   (set_attr "mode" "QI")
-   (set_attr "prefix_rex" "0")
-   (set_attr "prefix_rep" "1")])
-
 ;; The same, but the count is not known to not be zero.
 
 (define_expand "cmpstrnqi_1"
@@ -15868,46 +15688,33 @@ 
 
 (define_insn "*cmpstrnqi_1"
   [(set (reg:CC FLAGS_REG)
-	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
+	(if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
 			     (const_int 0))
-	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
-		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
+	  (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
+		      (mem:BLK (match_operand:P 5 "register_operand" "1")))
 	  (const_int 0)))
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (use (reg:CC FLAGS_REG))
-   (clobber (match_operand:SI 0 "register_operand" "=S"))
-   (clobber (match_operand:SI 1 "register_operand" "=D"))
-   (clobber (match_operand:SI 2 "register_operand" "=c"))]
-  "!TARGET_64BIT"
+   (clobber (match_operand:P 0 "register_operand" "=S"))
+   (clobber (match_operand:P 1 "register_operand" "=D"))
+   (clobber (match_operand:P 2 "register_operand" "=c"))]
+  ""
   "repz{%;} cmpsb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set (attr "prefix_rex")
+	(if_then_else
+	  (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+	  (const_string "0")
+	  (const_string "*")))
    (set_attr "prefix_rep" "1")])
 
-(define_insn "*cmpstrnqi_rex_1"
-  [(set (reg:CC FLAGS_REG)
-	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
-			     (const_int 0))
-	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
-		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
-	  (const_int 0)))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (use (reg:CC FLAGS_REG))
-   (clobber (match_operand:DI 0 "register_operand" "=S"))
-   (clobber (match_operand:DI 1 "register_operand" "=D"))
-   (clobber (match_operand:DI 2 "register_operand" "=c"))]
-  "TARGET_64BIT"
-  "repz{%;} cmpsb"
-  [(set_attr "type" "str")
-   (set_attr "mode" "QI")
-   (set_attr "prefix_rex" "0")
-   (set_attr "prefix_rep" "1")])
-
-(define_expand "strlensi"
-  [(set (match_operand:SI 0 "register_operand" "")
-	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
-		    (match_operand:QI 2 "immediate_operand" "")
-		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
+(define_expand "strlen<mode>"
+  [(set (match_operand:SWI48x 0 "register_operand" "")
+	(unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
+			(match_operand:QI 2 "immediate_operand" "")
+			(match_operand 3 "immediate_operand" "")]
+		       UNSPEC_SCAS))]
   ""
 {
  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
@@ -15916,55 +15723,33 @@ 
    FAIL;
 })
 
-(define_expand "strlendi"
-  [(set (match_operand:DI 0 "register_operand" "")
-	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
-		    (match_operand:QI 2 "immediate_operand" "")
-		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
-  ""
-{
- if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
-   DONE;
- else
-   FAIL;
-})
-
 (define_expand "strlenqi_1"
-  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
+  [(parallel [(set (match_operand 0 "register_operand" "")
+		   (match_operand 2 "" ""))
 	      (clobber (match_operand 1 "register_operand" ""))
 	      (clobber (reg:CC FLAGS_REG))])]
   ""
   "ix86_current_function_needs_cld = 1;")
 
 (define_insn "*strlenqi_1"
-  [(set (match_operand:SI 0 "register_operand" "=&c")
-	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
-		    (match_operand:QI 2 "register_operand" "a")
-		    (match_operand:SI 3 "immediate_operand" "i")
-		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
-   (clobber (match_operand:SI 1 "register_operand" "=D"))
+  [(set (match_operand:P 0 "register_operand" "=&c")
+	(unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
+		   (match_operand:QI 2 "register_operand" "a")
+		   (match_operand:P 3 "immediate_operand" "i")
+		   (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
+   (clobber (match_operand:P 1 "register_operand" "=D"))
    (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_64BIT"
+  ""
   "repnz{%;} scasb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set (attr "prefix_rex")
+	(if_then_else
+	  (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+	  (const_string "0")
+	  (const_string "*")))
    (set_attr "prefix_rep" "1")])
 
-(define_insn "*strlenqi_rex_1"
-  [(set (match_operand:DI 0 "register_operand" "=&c")
-	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
-		    (match_operand:QI 2 "register_operand" "a")
-		    (match_operand:DI 3 "immediate_operand" "i")
-		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
-   (clobber (match_operand:DI 1 "register_operand" "=D"))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT"
-  "repnz{%;} scasb"
-  [(set_attr "type" "str")
-   (set_attr "mode" "QI")
-   (set_attr "prefix_rex" "0")
-   (set_attr "prefix_rep" "1")])
-
 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
 ;; handled in combine, but it is not currently up to the task.
 ;; When used for their truth value, the cmpstrn* expanders generate