Patchwork [i386] : Macroize zero_extend and sign_extend patterns

login
register
mail settings
Submitter Uros Bizjak
Date Aug. 30, 2010, 7:30 a.m.
Message ID <AANLkTinkFj-Gx4Z4D2Z_aedCw7902hk8gnzsdzeyfhzx@mail.gmail.com>
Download mbox | patch
Permalink /patch/63003/
State New
Headers show

Comments

Uros Bizjak - Aug. 30, 2010, 7:30 a.m.
Hello!

2010-08-30  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/i386.md (zero_extendsidi2_1): Rename from
	zero_extendsidi2_32.
	(zero_extend<mode>di2): Macroize insn from zero_extend{qi,hi}di2
	using SWI12 mode iterator.
	(zero_extendhisi2_and): Merge insn pattern and corresponding spliter
	to define_insn_and_split pattern.
	(zero_extendqi<mode>2): Macroize expander from zero_extendqi{hi,si}2
	using SWI24 mode iterator.
	(*zero_extendqi<mode>2_and): Macroize insn from
	*zero_extendqi{hi,si}2_and using SWI24 mode iterator.
	(*zero_extendqi<mode>2_movzbl_and): Macroize insn from
	*zero_extendqihi2_movzbw_and and *zero_extendqisi2_movzbl_and using
	SWI24 mode iterator.
	(*zero_extendqi<mode>2_movzbl): Ditto from
	*zero_extendqi{hi,si}2_movzbl.
	(extendsidi2_1): Rename from extendsidi2_32.
	(extend<mode>di2): Macroize insn from extend{qi,hi}di2 using
	SWI12 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 163630)
+++ config/i386/i386.md	(working copy)
@@ -3587,9 +3587,92 @@ 
 
 ;; Zero extension instructions
 
+(define_expand "zero_extendsidi2"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
+	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
+  ""
+{
+  if (!TARGET_64BIT)
+    {
+      emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
+      DONE;
+    }
+})
+
+(define_insn "*zero_extendsidi2_rex64"
+  [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
+	(zero_extend:DI
+	 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
+  "TARGET_64BIT"
+  "@
+   mov\t{%k1, %k0|%k0, %k1}
+   #
+   movd\t{%1, %0|%0, %1}
+   movd\t{%1, %0|%0, %1}
+   %vmovd\t{%1, %0|%0, %1}
+   %vmovd\t{%1, %0|%0, %1}"
+  [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
+   (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
+   (set_attr "prefix_0f" "0,*,*,*,*,*")
+   (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
+
+(define_split
+  [(set (match_operand:DI 0 "memory_operand" "")
+     	(zero_extend:DI (match_dup 0)))]
+  "TARGET_64BIT"
+  [(set (match_dup 4) (const_int 0))]
+  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
+;; %%% Kill me once multi-word ops are sane.
+(define_insn "zero_extendsidi2_1"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
+	(zero_extend:DI
+	 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_64BIT"
+  "@
+   #
+   #
+   #
+   movd\t{%1, %0|%0, %1}
+   movd\t{%1, %0|%0, %1}
+   %vmovd\t{%1, %0|%0, %1}
+   %vmovd\t{%1, %0|%0, %1}"
+  [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
+   (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
+   (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
+
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_64BIT && reload_completed
+   && true_regnum (operands[0]) == true_regnum (operands[1])"
+  [(set (match_dup 4) (const_int 0))]
+  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
+(define_split
+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
+	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_64BIT && reload_completed
+   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 4) (const_int 0))]
+  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
+(define_insn "zero_extend<mode>di2"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI
+	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
+  "TARGET_64BIT"
+  "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
+  [(set_attr "type" "imovx")
+   (set_attr "mode" "SI")])
+
 (define_expand "zero_extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "")
-     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
+	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
   ""
 {
   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
@@ -3600,92 +3683,55 @@ 
     }
 })
 
-(define_insn "zero_extendhisi2_and"
+(define_insn_and_split "zero_extendhisi2_and"
   [(set (match_operand:SI 0 "register_operand" "=r")
-     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
+	(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
   "#"
+  "&& reload_completed"
+  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
+	      (clobber (reg:CC FLAGS_REG))])]
+  ""
   [(set_attr "type" "alu1")
    (set_attr "mode" "SI")])
 
-(define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
-   && optimize_function_for_speed_p (cfun)"
-  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
-	      (clobber (reg:CC FLAGS_REG))])]
-  "")
-
 (define_insn "*zero_extendhisi2_movzwl"
   [(set (match_operand:SI 0 "register_operand" "=r")
-     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
+	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
   "!TARGET_ZERO_EXTEND_WITH_AND
    || optimize_function_for_size_p (cfun)"
   "movz{wl|x}\t{%1, %0|%0, %1}"
   [(set_attr "type" "imovx")
    (set_attr "mode" "SI")])
 
-(define_expand "zero_extendqihi2"
+(define_expand "zero_extendqi<mode>2"
   [(parallel
-    [(set (match_operand:HI 0 "register_operand" "")
-       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
+    [(set (match_operand:SWI24 0 "register_operand" "")
+	  (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
      (clobber (reg:CC FLAGS_REG))])]
   ""
   "")
 
-(define_insn "*zero_extendqihi2_and"
-  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
-     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
+(define_insn "*zero_extendqi<mode>2_and"
+  [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
+	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
   "#"
   [(set_attr "type" "alu1")
-   (set_attr "mode" "HI")])
+   (set_attr "mode" "<MODE>")])
 
-(define_insn "*zero_extendqihi2_movzbw_and"
-  [(set (match_operand:HI 0 "register_operand" "=r,r")
-     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
-   (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
-  "#"
-  [(set_attr "type" "imovx,alu1")
-   (set_attr "mode" "HI")])
-
-; zero extend to SImode here to avoid partial register stalls
-(define_insn "*zero_extendqihi2_movzbl"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
-  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
-   && reload_completed"
-  "movz{bl|x}\t{%1, %k0|%k0, %1}"
-  [(set_attr "type" "imovx")
-   (set_attr "mode" "SI")])
-
-;; For the movzbw case strip only the clobber
-(define_split
-  [(set (match_operand:HI 0 "register_operand" "")
-	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "reload_completed
-   && (!TARGET_ZERO_EXTEND_WITH_AND
-       || optimize_function_for_size_p (cfun))
-   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
-  [(set (match_operand:HI 0 "register_operand" "")
-	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
-
 ;; When source and destination does not overlap, clear destination
 ;; first and then do the movb
 (define_split
-  [(set (match_operand:HI 0 "register_operand" "")
-	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
+  [(set (match_operand:SWI24 0 "register_operand" "")
+	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "reload_completed
+   && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
    && ANY_QI_REG_P (operands[0])
-   && (TARGET_ZERO_EXTEND_WITH_AND
-       && optimize_function_for_speed_p (cfun))
+   && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
    && !reg_overlap_mentioned_p (operands[0], operands[1])"
   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
 {
@@ -3693,206 +3739,62 @@ 
   ix86_expand_clear (operands[0]);
 })
 
-;; Rest is handled by single and.
-(define_split
-  [(set (match_operand:HI 0 "register_operand" "")
-	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
+(define_insn "*zero_extendqi<mode>2_movzbl_and"
+  [(set (match_operand:SWI24 0 "register_operand" "=r,r")
+	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
    (clobber (reg:CC FLAGS_REG))]
-  "reload_completed
-   && true_regnum (operands[0]) == true_regnum (operands[1])"
-  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
-	      (clobber (reg:CC FLAGS_REG))])]
-  "")
-
-(define_expand "zero_extendqisi2"
-  [(parallel
-    [(set (match_operand:SI 0 "register_operand" "")
-       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
-     (clobber (reg:CC FLAGS_REG))])]
-  ""
-  "")
-
-(define_insn "*zero_extendqisi2_and"
-  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
-     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
-  "#"
-  [(set_attr "type" "alu1")
-   (set_attr "mode" "SI")])
-
-(define_insn "*zero_extendqisi2_movzbl_and"
-  [(set (match_operand:SI 0 "register_operand" "=r,r")
-     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
-   (clobber (reg:CC FLAGS_REG))]
   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
   "#"
   [(set_attr "type" "imovx,alu1")
-   (set_attr "mode" "SI")])
+   (set_attr "mode" "<MODE>")])
 
-(define_insn "*zero_extendqisi2_movzbl"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
-  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
-   && reload_completed"
-  "movz{bl|x}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "imovx")
-   (set_attr "mode" "SI")])
-
 ;; For the movzbl case strip only the clobber
 (define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
+  [(set (match_operand:SWI24 0 "register_operand" "")
+	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "reload_completed
    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
   [(set (match_dup 0)
-	(zero_extend:SI (match_dup 1)))])
+	(zero_extend:SWI24 (match_dup 1)))])
 
-;; When source and destination does not overlap, clear destination
-;; first and then do the movb
-(define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
+; zero extend to SImode to avoid partial register stalls
+(define_insn "*zero_extendqi<mode>2_movzbl"
+  [(set (match_operand:SWI24 0 "register_operand" "=r")
+	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
   "reload_completed
-   && ANY_QI_REG_P (operands[0])
-   && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
-   && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
-   && !reg_overlap_mentioned_p (operands[0], operands[1])"
-  [(set (strict_low_part (match_dup 2)) (match_dup 1))]
-{
-  operands[2] = gen_lowpart (QImode, operands[0]);
-  ix86_expand_clear (operands[0]);
-})
+   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
+  "movz{bl|x}\t{%1, %k0|%k0, %1}"
+  [(set_attr "type" "imovx")
+   (set_attr "mode" "SI")])
 
 ;; Rest is handled by single and.
 (define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
+  [(set (match_operand:SWI24 0 "register_operand" "")
+	(zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "reload_completed
    && true_regnum (operands[0]) == true_regnum (operands[1])"
-  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
+  [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
 	      (clobber (reg:CC FLAGS_REG))])]
   "")
-
-;; %%% Kill me once multi-word ops are sane.
-(define_expand "zero_extendsidi2"
-  [(set (match_operand:DI 0 "register_operand" "")
-     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
-  ""
-{
-  if (!TARGET_64BIT)
-    {
-      emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
-      DONE;
-    }
-})
-
-(define_insn "zero_extendsidi2_32"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
-	(zero_extend:DI
-	 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
-   (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_64BIT"
-  "@
-   #
-   #
-   #
-   movd\t{%1, %0|%0, %1}
-   movd\t{%1, %0|%0, %1}
-   %vmovd\t{%1, %0|%0, %1}
-   %vmovd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
-   (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
-   (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
-
-(define_insn "zero_extendsidi2_rex64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
-     (zero_extend:DI
-       (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
-  "TARGET_64BIT"
-  "@
-   mov\t{%k1, %k0|%k0, %k1}
-   #
-   movd\t{%1, %0|%0, %1}
-   movd\t{%1, %0|%0, %1}
-   %vmovd\t{%1, %0|%0, %1}
-   %vmovd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
-   (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
-   (set_attr "prefix_0f" "0,*,*,*,*,*")
-   (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
-
-(define_split
-  [(set (match_operand:DI 0 "memory_operand" "")
-     (zero_extend:DI (match_dup 0)))]
-  "TARGET_64BIT"
-  [(set (match_dup 4) (const_int 0))]
-  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
-
-(define_split
-  [(set (match_operand:DI 0 "register_operand" "")
-	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_64BIT && reload_completed
-   && true_regnum (operands[0]) == true_regnum (operands[1])"
-  [(set (match_dup 4) (const_int 0))]
-  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
-
-(define_split
-  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_64BIT && reload_completed
-   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
-  [(set (match_dup 3) (match_dup 1))
-   (set (match_dup 4) (const_int 0))]
-  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
-
-(define_insn "zero_extendhidi2"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-  "TARGET_64BIT"
-  "movz{wl|x}\t{%1, %k0|%k0, %1}"
-  [(set_attr "type" "imovx")
-   (set_attr "mode" "SI")])
-
-(define_insn "zero_extendqidi2"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
-  "TARGET_64BIT"
-  "movz{bl|x}\t{%1, %k0|%k0, %1}"
-  [(set_attr "type" "imovx")
-   (set_attr "mode" "SI")])
 
 ;; Sign extension instructions
 
 (define_expand "extendsidi2"
-  [(parallel [(set (match_operand:DI 0 "register_operand" "")
-		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
-	      (clobber (reg:CC FLAGS_REG))
-	      (clobber (match_scratch:SI 2 ""))])]
+  [(set (match_operand:DI 0 "register_operand" "")
+	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
   ""
 {
-  if (TARGET_64BIT)
+  if (!TARGET_64BIT)
     {
-      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
+      emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
       DONE;
     }
 })
 
-(define_insn "*extendsidi2_1"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
-	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
-   (clobber (reg:CC FLAGS_REG))
-   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
-  "!TARGET_64BIT"
-  "#")
-
-(define_insn "extendsidi2_rex64"
+(define_insn "*extendsidi2_rex64"
   [(set (match_operand:DI 0 "register_operand" "=*a,r")
 	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
   "TARGET_64BIT"
@@ -3904,22 +3806,14 @@ 
    (set_attr "prefix_0f" "0")
    (set_attr "modrm" "0,1")])
 
-(define_insn "extendhidi2"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
-  "TARGET_64BIT"
-  "movs{wq|x}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "imovx")
-   (set_attr "mode" "DI")])
+(define_insn "extendsidi2_1"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
+	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
+   (clobber (reg:CC FLAGS_REG))
+   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
+  "!TARGET_64BIT"
+  "#")
 
-(define_insn "extendqidi2"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
-  "TARGET_64BIT"
-  "movs{bq|x}\t{%1, %0|%0, %1}"
-   [(set_attr "type" "imovx")
-    (set_attr "mode" "DI")])
-
 ;; Extend to memory case when source register does die.
 (define_split
   [(set (match_operand:DI 0 "memory_operand" "")
@@ -3995,6 +3889,15 @@ 
   DONE;
 })
 
+(define_insn "extend<mode>di2"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(sign_extend:DI
+	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
+  "TARGET_64BIT"
+  "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
+  [(set_attr "type" "imovx")
+   (set_attr "mode" "DI")])
+
 (define_insn "extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "=*a,r")
 	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
@@ -4024,7 +3927,8 @@ 
 (define_insn "*extendhisi2_zext"
   [(set (match_operand:DI 0 "register_operand" "=*a,r")
 	(zero_extend:DI
-	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
+	 (sign_extend:SI
+	  (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
   "TARGET_64BIT"
 {
   switch (get_attr_prefix_0f (insn))
@@ -4048,6 +3952,23 @@ 
 	(const_string "0")
 	(const_string "1")))])
 
+(define_insn "extendqisi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
+  ""
+  "movs{bl|x}\t{%1, %0|%0, %1}"
+   [(set_attr "type" "imovx")
+    (set_attr "mode" "SI")])
+
+(define_insn "*extendqisi2_zext"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI
+	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
+  "TARGET_64BIT"
+  "movs{bl|x}\t{%1, %k0|%k0, %1}"
+   [(set_attr "type" "imovx")
+    (set_attr "mode" "SI")])
+
 (define_insn "extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=*a,r")
 	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
@@ -4073,23 +3994,6 @@ 
      (if_then_else (eq_attr "prefix_0f" "0")
 	(const_string "0")
 	(const_string "1")))])
-
-(define_insn "extendqisi2"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
-  ""
-  "movs{bl|x}\t{%1, %0|%0, %1}"
-   [(set_attr "type" "imovx")
-    (set_attr "mode" "SI")])
-
-(define_insn "*extendqisi2_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-	(zero_extend:DI
-	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
-  "TARGET_64BIT"
-  "movs{bl|x}\t{%1, %k0|%k0, %1}"
-   [(set_attr "type" "imovx")
-    (set_attr "mode" "SI")])
 
 ;; Conversions between float and double.