OSDN Git Service

* config/i386/i386.md (any_extend): New code iterator.
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Oct 2009 20:09:01 +0000 (20:09 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Oct 2009 20:09:01 +0000 (20:09 +0000)
(u, s): New code attributes.
(sgnprefix): Ditto.
(DWIH): Rewrite as code iterator for SI and DI modes.
(DWI): Rewrite as mode attribute.
(dwi): New mode attribute.
(di): Depend on SI mode and DI mode.
(doubleint_general_operand): Remove mode attribute.

(*lea_1): Macroize insn from *lea_1_rex64 and *lea_1 patterns using
DWIH mode iterator.

(*add<mode>3_doubleword): Use DWIH as the base mode iterator.
(*sub<mode>3_doubleword): Ditto.

(mul<mode>3): Macroize expander from mul{hi,si,di}3 patterns
using SWIM248 mode iterator.
(*mul<mode>3_1): Macroize insn from mul{si,di}3_1 patterns
using SWI48 mode iterator.
(<u>mul<mode><dwi>3): Macroize expander from {,u}mul{sidi,diti}3
patterns using DWIH mode iterator and any_extend code iterator.
(<u>mulqihi3): Macroize expander from {,u}mulqihi3 patterns
using any_extend code iterator.
(*<u>mul<mode><dwi>3_1): Macroize insn from {,u}mul{sidi,diti}3_1
patterns using DWIH mode iterator and any_extend code iterator.
(*<u>mulqihi3_1): Macroize insn from {,u}mulqihi3_1 patterns
using any_extend code iterator.
(<s>mul<mode>3_highpart): Macroize expander from
{s,u}mul{si,di}3_highpart patterns using DWIH mode iterator
and any_extend code iterator.
(*<s>muldi3_highpart_1): Macroize insn from
*{s,u}muldi3_highpart_rex64 patterns using any_extend code iterator.
(*<s>mulsi3_highpart_1): Macroize insn from *{s,u}mulsi3_highpart_1
patterns using any_extend code iterator.
(*<s>mulsi3_highpart_zext): Macroize insn from
*{s,u}mulsi3_highpart_zext patterns using any_extend code iterator.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152539 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.md

index b1a88a3..ae03a3b 100644 (file)
@@ -1,3 +1,42 @@
+2009-10-07  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.md (any_extend): New code iterator.
+       (u, s): New code attributes.
+       (sgnprefix): Ditto.
+       (DWIH): Rewrite as code iterator for SI and DI modes.
+       (DWI): Rewrite as mode attribute.
+       (dwi): New mode attribute.
+       (di): Depend on SI mode and DI mode.
+       (doubleint_general_operand): Remove mode attribute.
+
+       (*lea_1): Macroize insn from *lea_1_rex64 and *lea_1 patterns using
+       DWIH mode iterator.
+
+       (*add<mode>3_doubleword): Use DWIH as the base mode iterator.
+       (*sub<mode>3_doubleword): Ditto.
+
+       (mul<mode>3): Macroize expander from mul{hi,si,di}3 patterns
+       using SWIM248 mode iterator.
+       (*mul<mode>3_1): Macroize insn from mul{si,di}3_1 patterns
+       using SWI48 mode iterator.
+       (<u>mul<mode><dwi>3): Macroize expander from {,u}mul{sidi,diti}3
+       patterns using DWIH mode iterator and any_extend code iterator.
+       (<u>mulqihi3): Macroize expander from {,u}mulqihi3 patterns
+       using any_extend code iterator.
+       (*<u>mul<mode><dwi>3_1): Macroize insn from {,u}mul{sidi,diti}3_1
+       patterns using DWIH mode iterator and any_extend code iterator.
+       (*<u>mulqihi3_1): Macroize insn from {,u}mulqihi3_1 patterns
+       using any_extend code iterator.
+       (<s>mul<mode>3_highpart): Macroize expander from
+       {s,u}mul{si,di}3_highpart patterns using DWIH mode iterator
+       and any_extend code iterator.
+       (*<s>muldi3_highpart_1): Macroize insn from
+       *{s,u}muldi3_highpart_rex64 patterns using any_extend code iterator.
+       (*<s>mulsi3_highpart_1): Macroize insn from *{s,u}mulsi3_highpart_1
+       patterns using any_extend code iterator.
+       (*<s>mulsi3_highpart_zext): Macroize insn from
+       *{s,u}mulsi3_highpart_zext patterns using any_extend code iterator.
+
 2009-10-07  Jakub Jelinek  <jakub@redhat.com>
 
        * dwarf2out.c (tree_add_const_value_attribute_for_decl): Don't add
        (enum processor_type): Add PROCESSOR_PPCA2.
        * config/rs6000/rs6000.c (ppca2_cost): New costs.
        (rs6000_override_options): Add "a2" to processor_target_table.
-       Update rs6000_always_hint logic.  Correctly set rs6000_cost for
-       a2.
-       * doc/invoke.texi (RS/6000 and PowerPC Options): Document
-       -mcpu=a2.
+       Update rs6000_always_hint logic.  Correctly set rs6000_cost for a2.
+       * doc/invoke.texi (RS/6000 and PowerPC Options): Document -mcpu=a2.
 
 2009-10-06  Uros Bizjak  <ubizjak@gmail.com>
 
index d24f7ec..6b68c54 100644 (file)
 ;; Base name for x87 insn mnemonic.
 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
 
+;; Used in signed and unsigned widening multiplications.
+(define_code_iterator any_extend [sign_extend zero_extend])
+
+;; Various insn prefixes for widening operations.
+(define_code_attr u [(sign_extend "") (zero_extend "u")])
+(define_code_attr s [(sign_extend "s") (zero_extend "u")])
+
+;; Instruction prefix for widening operations.
+(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
+
 ;; All single word integer modes.
 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
 
 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
                               SI (DI "TARGET_64BIT")])
 
-;; Double word integer modes.
-(define_mode_iterator DWI [(DI "!TARGET_64BIT")
-                          (TI "TARGET_64BIT")])
-
 ;; Half mode for double word integer modes.
-(define_mode_attr DWIH [(DI "SI") (TI "DI")])
+(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
+                           (DI "TARGET_64BIT")])
+
+;; Double word integer modes.
+(define_mode_attr DWI [(SI "DI") (DI "TI")])
+(define_mode_attr dwi [(SI "di") (DI "ti")])
 
 ;; Instruction suffix for integer modes.
 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
 (define_mode_attr g [(SI "g") (DI "rme")])
 
 ;; Immediate operand constraint for double integer modes.
-(define_mode_attr di [(DI "iF") (TI "e")])
+(define_mode_attr di [(SI "iF") (DI "e")])
 
 ;; General operand predicate for integer modes.
 (define_mode_attr general_operand
         (DI "x86_64_general_operand")
         (TI "x86_64_general_operand")])
 
-;; General operand predicate for double integer modes.
-(define_mode_attr doubleint_general_operand
-       [(DI "general_operand")
-        (TI "x86_64_general_operand")])
-
 ;; SSE and x87 SFmode and DFmode floating point modes
 (define_mode_iterator MODEF [SF DF])
 
 ;; This mode iterator allows :P to be used for patterns that operate on
 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
-
 \f
 ;; Scheduling descriptions
 
   ""
   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
 
-(define_insn_and_split "*add<mode>3_doubleword"
-  [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o")
-       (plus:DWI
-         (match_operand:DWI 1 "nonimmediate_operand" "%0,0")
-         (match_operand:DWI 2 "<doubleint_general_operand>" "ro<di>,r<di>")))
+(define_insn_and_split "*add<dwi>3_doubleword"
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
+       (plus:<DWI>
+         (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
+         (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
   "#"
   "reload_completed"
   [(parallel [(set (reg:CC FLAGS_REG)
                   (unspec:CC [(match_dup 1) (match_dup 2)]
                              UNSPEC_ADD_CARRY))
              (set (match_dup 0)
-                  (plus:<DWIH> (match_dup 1) (match_dup 2)))])
+                  (plus:DWIH (match_dup 1) (match_dup 2)))])
    (parallel [(set (match_dup 3)
-                  (plus:<DWIH>
-                    (plus:<DWIH>
-                      (ltu:<DWIH> (reg:CC FLAGS_REG) (const_int 0))
+                  (plus:DWIH
+                    (plus:DWIH
+                      (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
                       (match_dup 4))
                     (match_dup 5)))
              (clobber (reg:CC FLAGS_REG))])]
-  "split_<mode> (&operands[0], 3, &operands[0], &operands[3]);")
+  "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
 
 (define_insn "add<mode>3_carry"
   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
   [(set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*lea_1_rex64"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (match_operand:DI 1 "no_seg_address_operand" "p"))]
-  "TARGET_64BIT"
-  "lea{q}\t{%a1, %0|%0, %a1}"
+(define_insn "*lea_1"
+  [(set (match_operand:DWIH 0 "register_operand" "=r")
+       (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
+  ""
+  "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
-   (set_attr "mode" "DI")])
+   (set_attr "mode" "<MODE>")])
 
-(define_insn "*lea_1"
+(define_insn "*lea_2"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (match_operand:SI 1 "no_seg_address_operand" "p"))]
-  "!TARGET_64BIT"
+       (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
+  "TARGET_64BIT"
   "lea{l}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
-(define_insn "*lea_1_zext"
+(define_insn "*lea_2_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
-        (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
+         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %k0|%k0, %a1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
-(define_insn "*lea_2_rex64"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
-  "TARGET_64BIT"
-  "lea{l}\t{%a1, %0|%0, %a1}"
-  [(set_attr "type" "lea")
-   (set_attr "mode" "SI")])
-
 (define_insn "*add<mode>_1"
   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
        (plus:SWI48
   ""
   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
 
-(define_insn_and_split "*sub<mode>3_doubleword"
-  [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o")
-       (minus:DWI
-         (match_operand:DWI 1 "nonimmediate_operand" "0,0")
-         (match_operand:DWI 2 "<doubleint_general_operand>" "ro<di>,r<di>")))
+(define_insn_and_split "*sub<dwi>3_doubleword"
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
+       (minus:<DWI>
+         (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
+         (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
    (clobber (reg:CC FLAGS_REG))]
   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
   "#"
   [(parallel [(set (reg:CC FLAGS_REG)
                   (compare:CC (match_dup 1) (match_dup 2)))
              (set (match_dup 0)
-                  (minus:<DWIH> (match_dup 1) (match_dup 2)))])
+                  (minus:DWIH (match_dup 1) (match_dup 2)))])
    (parallel [(set (match_dup 3)
-                  (minus:<DWIH>
+                  (minus:DWIH
                     (match_dup 4)
-                    (plus:<DWIH>
-                      (ltu:<DWIH> (reg:CC FLAGS_REG) (const_int 0))
+                    (plus:DWIH
+                      (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
                       (match_dup 5))))
              (clobber (reg:CC FLAGS_REG))])]
-  "split_<mode> (&operands[0], 3, &operands[0], &operands[3]);")
+  "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
 
 (define_insn "sub<mode>3_carry"
   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
 \f
 ;; Multiply instructions
 
-(define_expand "muldi3"
-  [(parallel [(set (match_operand:DI 0 "register_operand" "")
-                  (mult:DI (match_operand:DI 1 "register_operand" "")
-                           (match_operand:DI 2 "x86_64_general_operand" "")))
+(define_expand "mul<mode>3"
+  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
+                  (mult:SWIM248
+                    (match_operand:SWIM248 1 "register_operand" "")
+                    (match_operand:SWIM248 2 "<general_operand>" "")))
              (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_64BIT"
+  ""
   "")
 
-;; On AMDFAM10
-;; IMUL reg64, reg64, imm8     Direct
-;; IMUL reg64, mem64, imm8     VectorPath
-;; IMUL reg64, reg64, imm32    Direct
-;; IMUL reg64, mem64, imm32    VectorPath
-;; IMUL reg64, reg64           Direct
-;; IMUL reg64, mem64           Direct
-
-(define_insn "*muldi3_1_rex64"
-  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
-       (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
-                (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "@
-   imul{q}\t{%2, %1, %0|%0, %1, %2}
-   imul{q}\t{%2, %1, %0|%0, %1, %2}
-   imul{q}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "imul")
-   (set_attr "prefix_0f" "0,0,1")
-   (set (attr "athlon_decode")
-       (cond [(eq_attr "cpu" "athlon")
-                 (const_string "vector")
-              (eq_attr "alternative" "1")
-                 (const_string "vector")
-              (and (eq_attr "alternative" "2")
-                   (match_operand 1 "memory_operand" ""))
-                 (const_string "vector")]
-             (const_string "direct")))
-   (set (attr "amdfam10_decode")
-       (cond [(and (eq_attr "alternative" "0,1")
-                   (match_operand 1 "memory_operand" ""))
-                 (const_string "vector")]
-             (const_string "direct")))
-   (set_attr "mode" "DI")])
-
-(define_expand "mulsi3"
-  [(parallel [(set (match_operand:SI 0 "register_operand" "")
-                  (mult:SI (match_operand:SI 1 "register_operand" "")
-                           (match_operand:SI 2 "general_operand" "")))
+(define_expand "mulqi3"
+  [(parallel [(set (match_operand:QI 0 "register_operand" "")
+                  (mult:QI
+                    (match_operand:QI 1 "register_operand" "")
+                    (match_operand:QI 2 "nonimmediate_operand" "")))
              (clobber (reg:CC FLAGS_REG))])]
-  ""
+  "TARGET_QIMODE_MATH"
   "")
 
 ;; On AMDFAM10
-;; IMUL reg32, reg32, imm8     Direct
-;; IMUL reg32, mem32, imm8     VectorPath
-;; IMUL reg32, reg32, imm32    Direct
-;; IMUL reg32, mem32, imm32    VectorPath
-;; IMUL reg32, reg32           Direct
-;; IMUL reg32, mem32           Direct
-
-(define_insn "*mulsi3_1"
-  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
-       (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
-                (match_operand:SI 2 "general_operand" "K,i,mr")))
+;; IMUL reg32/64, reg32/64, imm8       Direct
+;; IMUL reg32/64, mem32/64, imm8       VectorPath
+;; IMUL reg32/64, reg32/64, imm32      Direct
+;; IMUL reg32/64, mem32/64, imm32      VectorPath
+;; IMUL reg32/64, reg32/64             Direct
+;; IMUL reg32/64, mem32/64             Direct
+
+(define_insn "*mul<mode>3_1"
+  [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
+       (mult:SWI48
+         (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
+         (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
    (clobber (reg:CC FLAGS_REG))]
   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
   "@
-   imul{l}\t{%2, %1, %0|%0, %1, %2}
-   imul{l}\t{%2, %1, %0|%0, %1, %2}
-   imul{l}\t{%2, %0|%0, %2}"
+   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   imul{<imodesuffix>}\t{%2, %0|%0, %2}"
   [(set_attr "type" "imul")
    (set_attr "prefix_0f" "0,0,1")
    (set (attr "athlon_decode")
                    (match_operand 1 "memory_operand" ""))
                  (const_string "vector")]
              (const_string "direct")))
-   (set_attr "mode" "SI")])
+   (set_attr "mode" "<MODE>")])
 
 (define_insn "*mulsi3_1_zext"
   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
              (const_string "direct")))
    (set_attr "mode" "SI")])
 
-(define_expand "mulhi3"
-  [(parallel [(set (match_operand:HI 0 "register_operand" "")
-                  (mult:HI (match_operand:HI 1 "register_operand" "")
-                           (match_operand:HI 2 "general_operand" "")))
-             (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_HIMODE_MATH"
-  "")
-
 ;; On AMDFAM10
 ;; IMUL reg16, reg16, imm8     VectorPath
 ;; IMUL reg16, mem16, imm8     VectorPath
 ;; IMUL reg16, mem16, imm16    VectorPath
 ;; IMUL reg16, reg16           Direct
 ;; IMUL reg16, mem16           Direct
+
 (define_insn "*mulhi3_1"
   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
        (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
                 (match_operand:HI 2 "general_operand" "K,n,mr")))
    (clobber (reg:CC FLAGS_REG))]
-  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "TARGET_HIMODE_MATH
+   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
   "@
    imul{w}\t{%2, %1, %0|%0, %1, %2}
    imul{w}\t{%2, %1, %0|%0, %1, %2}
              (const_string "direct")))
    (set_attr "mode" "HI")])
 
-(define_expand "mulqi3"
-  [(parallel [(set (match_operand:QI 0 "register_operand" "")
-                  (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
-                           (match_operand:QI 2 "register_operand" "")))
-             (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_QIMODE_MATH"
-  "")
-
 ;;On AMDFAM10
 ;; MUL reg8    Direct
 ;; MUL mem8    Direct
    (set_attr "amdfam10_decode" "direct")
    (set_attr "mode" "QI")])
 
-(define_expand "umulqihi3"
-  [(parallel [(set (match_operand:HI 0 "register_operand" "")
-                  (mult:HI (zero_extend:HI
-                             (match_operand:QI 1 "nonimmediate_operand" ""))
-                           (zero_extend:HI
-                             (match_operand:QI 2 "register_operand" ""))))
+(define_expand "<u>mul<mode><dwi>3"
+  [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
+                  (mult:<DWI>
+                    (any_extend:<DWI>
+                      (match_operand:DWIH 1 "nonimmediate_operand" ""))
+                    (any_extend:<DWI>
+                      (match_operand:DWIH 2 "register_operand" ""))))
              (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_QIMODE_MATH"
+  ""
   "")
 
-(define_insn "*umulqihi3_1"
-  [(set (match_operand:HI 0 "register_operand" "=a")
-       (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
-                (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_QIMODE_MATH
-   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "mul{b}\t%2"
-  [(set_attr "type" "imul")
-   (set_attr "length_immediate" "0")
-   (set (attr "athlon_decode")
-     (if_then_else (eq_attr "cpu" "athlon")
-        (const_string "vector")
-        (const_string "direct")))
-   (set_attr "amdfam10_decode" "direct")
-   (set_attr "mode" "QI")])
-
-(define_expand "mulqihi3"
+(define_expand "<u>mulqihi3"
   [(parallel [(set (match_operand:HI 0 "register_operand" "")
-                  (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
-                           (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
+                  (mult:HI
+                    (any_extend:HI
+                      (match_operand:QI 1 "nonimmediate_operand" ""))
+                    (any_extend:HI
+                      (match_operand:QI 2 "register_operand" ""))))
              (clobber (reg:CC FLAGS_REG))])]
   "TARGET_QIMODE_MATH"
   "")
 
-(define_insn "*mulqihi3_insn"
-  [(set (match_operand:HI 0 "register_operand" "=a")
-       (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
-                (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_QIMODE_MATH
-   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "imul{b}\t%2"
-  [(set_attr "type" "imul")
-   (set_attr "length_immediate" "0")
-   (set (attr "athlon_decode")
-     (if_then_else (eq_attr "cpu" "athlon")
-        (const_string "vector")
-        (const_string "direct")))
-   (set_attr "amdfam10_decode" "direct")
-   (set_attr "mode" "QI")])
-
-(define_expand "umulditi3"
-  [(parallel [(set (match_operand:TI 0 "register_operand" "")
-                  (mult:TI (zero_extend:TI
-                             (match_operand:DI 1 "nonimmediate_operand" ""))
-                           (zero_extend:TI
-                             (match_operand:DI 2 "register_operand" ""))))
-             (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_64BIT"
-  "")
-
-(define_insn "*umulditi3_insn"
-  [(set (match_operand:TI 0 "register_operand" "=A")
-       (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
-                (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "mul{q}\t%2"
-  [(set_attr "type" "imul")
-   (set_attr "length_immediate" "0")
-   (set (attr "athlon_decode")
-     (if_then_else (eq_attr "cpu" "athlon")
-        (const_string "vector")
-        (const_string "double")))
-   (set_attr "amdfam10_decode" "double")
-   (set_attr "mode" "DI")])
-
-;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
-(define_expand "umulsidi3"
-  [(parallel [(set (match_operand:DI 0 "register_operand" "")
-                  (mult:DI (zero_extend:DI
-                             (match_operand:SI 1 "nonimmediate_operand" ""))
-                           (zero_extend:DI
-                             (match_operand:SI 2 "register_operand" ""))))
-             (clobber (reg:CC FLAGS_REG))])]
-  "!TARGET_64BIT"
-  "")
-
-(define_insn "*umulsidi3_insn"
-  [(set (match_operand:DI 0 "register_operand" "=A")
-       (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
-                (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
+(define_insn "*<u>mul<mode><dwi>3_1"
+  [(set (match_operand:<DWI> 0 "register_operand" "=A")
+       (mult:<DWI>
+         (any_extend:<DWI>
+           (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
+         (any_extend:<DWI>
+           (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
    (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_64BIT
-   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "mul{l}\t%2"
-  [(set_attr "type" "imul")
-   (set_attr "length_immediate" "0")
-   (set (attr "athlon_decode")
-     (if_then_else (eq_attr "cpu" "athlon")
-        (const_string "vector")
-        (const_string "double")))
-   (set_attr "amdfam10_decode" "double")
-   (set_attr "mode" "SI")])
-
-(define_expand "mulditi3"
-  [(parallel [(set (match_operand:TI 0 "register_operand" "")
-                  (mult:TI (sign_extend:TI
-                             (match_operand:DI 1 "nonimmediate_operand" ""))
-                           (sign_extend:TI
-                             (match_operand:DI 2 "register_operand" ""))))
-             (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_64BIT"
-  "")
-
-(define_insn "*mulditi3_insn"
-  [(set (match_operand:TI 0 "register_operand" "=A")
-       (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
-                (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "imul{q}\t%2"
+  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "<sgnprefix>mul{<imodesuffix>}\t%2"
   [(set_attr "type" "imul")
    (set_attr "length_immediate" "0")
    (set (attr "athlon_decode")
         (const_string "vector")
         (const_string "double")))
    (set_attr "amdfam10_decode" "double")
-   (set_attr "mode" "DI")])
-
-(define_expand "mulsidi3"
-  [(parallel [(set (match_operand:DI 0 "register_operand" "")
-                  (mult:DI (sign_extend:DI
-                             (match_operand:SI 1 "nonimmediate_operand" ""))
-                           (sign_extend:DI
-                             (match_operand:SI 2 "register_operand" ""))))
-             (clobber (reg:CC FLAGS_REG))])]
-  "!TARGET_64BIT"
-  "")
+   (set_attr "mode" "<MODE>")])
 
-(define_insn "*mulsidi3_insn"
-  [(set (match_operand:DI 0 "register_operand" "=A")
-       (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
-                (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
+(define_insn "*<u>mulqihi3_1"
+  [(set (match_operand:HI 0 "register_operand" "=a")
+       (mult:HI
+         (any_extend:HI
+           (match_operand:QI 1 "nonimmediate_operand" "%0"))
+         (any_extend:HI
+           (match_operand:QI 2 "nonimmediate_operand" "qm"))))
    (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_64BIT
+  "TARGET_QIMODE_MATH
    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "imul{l}\t%2"
+  "<sgnprefix>mul{b}\t%2"
   [(set_attr "type" "imul")
    (set_attr "length_immediate" "0")
    (set (attr "athlon_decode")
      (if_then_else (eq_attr "cpu" "athlon")
         (const_string "vector")
-        (const_string "double")))
-   (set_attr "amdfam10_decode" "double")
-   (set_attr "mode" "SI")])
+        (const_string "direct")))
+   (set_attr "amdfam10_decode" "direct")
+   (set_attr "mode" "QI")])
 
-(define_expand "umuldi3_highpart"
-  [(parallel [(set (match_operand:DI 0 "register_operand" "")
-                  (truncate:DI
-                    (lshiftrt:TI
-                      (mult:TI (zero_extend:TI
-                                 (match_operand:DI 1 "nonimmediate_operand" ""))
-                               (zero_extend:TI
-                                 (match_operand:DI 2 "register_operand" "")))
-                      (const_int 64))))
-             (clobber (match_scratch:DI 3 ""))
+(define_expand "<s>mul<mode>3_highpart"
+  [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
+                  (truncate:SWI48
+                    (lshiftrt:<DWI>
+                      (mult:<DWI>
+                        (any_extend:<DWI>
+                          (match_operand:SWI48 1 "nonimmediate_operand" ""))
+                        (any_extend:<DWI>
+                          (match_operand:SWI48 2 "register_operand" "")))
+                      (match_dup 4))))
+             (clobber (match_scratch:SWI48 3 ""))
              (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_64BIT"
-  "")
+  ""
+  "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
 
-(define_insn "*umuldi3_highpart_rex64"
+(define_insn "*<s>muldi3_highpart_1"
   [(set (match_operand:DI 0 "register_operand" "=d")
        (truncate:DI
          (lshiftrt:TI
-           (mult:TI (zero_extend:TI
-                      (match_operand:DI 1 "nonimmediate_operand" "%a"))
-                    (zero_extend:TI
-                      (match_operand:DI 2 "nonimmediate_operand" "rm")))
+           (mult:TI
+             (any_extend:TI
+               (match_operand:DI 1 "nonimmediate_operand" "%a"))
+             (any_extend:TI
+               (match_operand:DI 2 "nonimmediate_operand" "rm")))
            (const_int 64))))
    (clobber (match_scratch:DI 3 "=1"))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT
    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "mul{q}\t%2"
+  "<sgnprefix>mul{q}\t%2"
   [(set_attr "type" "imul")
    (set_attr "length_immediate" "0")
    (set (attr "athlon_decode")
    (set_attr "amdfam10_decode" "double")
    (set_attr "mode" "DI")])
 
-(define_expand "umulsi3_highpart"
-  [(parallel [(set (match_operand:SI 0 "register_operand" "")
-                  (truncate:SI
-                    (lshiftrt:DI
-                      (mult:DI (zero_extend:DI
-                                 (match_operand:SI 1 "nonimmediate_operand" ""))
-                               (zero_extend:DI
-                                 (match_operand:SI 2 "register_operand" "")))
-                      (const_int 32))))
-             (clobber (match_scratch:SI 3 ""))
-             (clobber (reg:CC FLAGS_REG))])]
-  ""
-  "")
-
-(define_insn "*umulsi3_highpart_insn"
+(define_insn "*<s>mulsi3_highpart_1"
   [(set (match_operand:SI 0 "register_operand" "=d")
        (truncate:SI
          (lshiftrt:DI
-           (mult:DI (zero_extend:DI
-                      (match_operand:SI 1 "nonimmediate_operand" "%a"))
-                    (zero_extend:DI
-                      (match_operand:SI 2 "nonimmediate_operand" "rm")))
+           (mult:DI
+             (any_extend:DI
+               (match_operand:SI 1 "nonimmediate_operand" "%a"))
+             (any_extend:DI
+               (match_operand:SI 2 "nonimmediate_operand" "rm")))
            (const_int 32))))
    (clobber (match_scratch:SI 3 "=1"))
    (clobber (reg:CC FLAGS_REG))]
   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "mul{l}\t%2"
+  "<sgnprefix>mul{l}\t%2"
   [(set_attr "type" "imul")
    (set_attr "length_immediate" "0")
    (set (attr "athlon_decode")
    (set_attr "amdfam10_decode" "double")
    (set_attr "mode" "SI")])
 
-(define_insn "*umulsi3_highpart_zext"
+(define_insn "*<s>mulsi3_highpart_zext"
   [(set (match_operand:DI 0 "register_operand" "=d")
        (zero_extend:DI (truncate:SI
          (lshiftrt:DI
-           (mult:DI (zero_extend:DI
+           (mult:DI (any_extend:DI
                       (match_operand:SI 1 "nonimmediate_operand" "%a"))
-                    (zero_extend:DI
+                    (any_extend:DI
                       (match_operand:SI 2 "nonimmediate_operand" "rm")))
            (const_int 32)))))
    (clobber (match_scratch:SI 3 "=1"))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT
    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "mul{l}\t%2"
+  "<sgnprefix>mul{l}\t%2"
   [(set_attr "type" "imul")
    (set_attr "length_immediate" "0")
    (set (attr "athlon_decode")
    (set_attr "amdfam10_decode" "double")
    (set_attr "mode" "SI")])
 
-(define_expand "smuldi3_highpart"
-  [(parallel [(set (match_operand:DI 0 "register_operand" "")
-                  (truncate:DI
-                    (lshiftrt:TI
-                      (mult:TI (sign_extend:TI
-                                 (match_operand:DI 1 "nonimmediate_operand" ""))
-                               (sign_extend:TI
-                                 (match_operand:DI 2 "register_operand" "")))
-                      (const_int 64))))
-             (clobber (match_scratch:DI 3 ""))
-             (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_64BIT"
-  "")
-
-(define_insn "*smuldi3_highpart_rex64"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-       (truncate:DI
-         (lshiftrt:TI
-           (mult:TI (sign_extend:TI
-                      (match_operand:DI 1 "nonimmediate_operand" "%a"))
-                    (sign_extend:TI
-                      (match_operand:DI 2 "nonimmediate_operand" "rm")))
-           (const_int 64))))
-   (clobber (match_scratch:DI 3 "=1"))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "imul{q}\t%2"
-  [(set_attr "type" "imul")
-   (set (attr "athlon_decode")
-     (if_then_else (eq_attr "cpu" "athlon")
-        (const_string "vector")
-        (const_string "double")))
-   (set_attr "amdfam10_decode" "double")
-   (set_attr "mode" "DI")])
-
-(define_expand "smulsi3_highpart"
-  [(parallel [(set (match_operand:SI 0 "register_operand" "")
-                  (truncate:SI
-                    (lshiftrt:DI
-                      (mult:DI (sign_extend:DI
-                                 (match_operand:SI 1 "nonimmediate_operand" ""))
-                               (sign_extend:DI
-                                 (match_operand:SI 2 "register_operand" "")))
-                      (const_int 32))))
-             (clobber (match_scratch:SI 3 ""))
-             (clobber (reg:CC FLAGS_REG))])]
-  ""
-  "")
-
-(define_insn "*smulsi3_highpart_insn"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (truncate:SI
-         (lshiftrt:DI
-           (mult:DI (sign_extend:DI
-                      (match_operand:SI 1 "nonimmediate_operand" "%a"))
-                    (sign_extend:DI
-                      (match_operand:SI 2 "nonimmediate_operand" "rm")))
-           (const_int 32))))
-   (clobber (match_scratch:SI 3 "=1"))
-   (clobber (reg:CC FLAGS_REG))]
-  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "imul{l}\t%2"
-  [(set_attr "type" "imul")
-   (set (attr "athlon_decode")
-     (if_then_else (eq_attr "cpu" "athlon")
-        (const_string "vector")
-        (const_string "double")))
-   (set_attr "amdfam10_decode" "double")
-   (set_attr "mode" "SI")])
-
-(define_insn "*smulsi3_highpart_zext"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-       (zero_extend:DI (truncate:SI
-         (lshiftrt:DI
-           (mult:DI (sign_extend:DI
-                      (match_operand:SI 1 "nonimmediate_operand" "%a"))
-                    (sign_extend:DI
-                      (match_operand:SI 2 "nonimmediate_operand" "rm")))
-           (const_int 32)))))
-   (clobber (match_scratch:SI 3 "=1"))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "imul{l}\t%2"
-  [(set_attr "type" "imul")
-   (set (attr "athlon_decode")
-     (if_then_else (eq_attr "cpu" "athlon")
-        (const_string "vector")
-        (const_string "double")))
-   (set_attr "amdfam10_decode" "double")
-   (set_attr "mode" "SI")])
-
 ;; The patterns that match these are at the end of this file.
 
 (define_expand "mulxf3"
   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
   "")
-
 \f
 ;; Divide instructions