* i386.md (type): Add new SSE/MMX subtypes, remove usused fop1.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Apr 2002 17:20:44 +0000 (17:20 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Apr 2002 17:20:44 +0000 (17:20 +0000)
(mode): Add vector modes
(i387): Kill attribute.
(unit): New attribute.
(length_immediate): Grok new types.
(prefix_data16, prefix_rep, prefix_0f): Fix for SSE/MMX.
(modrm): Use "unit".
(memory): Handle MMX/SSE properly.
(scheduling descriptions): Kill uses of fop1.
(sse, mmx, fp patterns): Set type and mode properly.

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

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

index 717d17e..26fdc00 100644 (file)
@@ -1,3 +1,16 @@
+Tue Apr 30 19:15:36 CEST 2002  Jan Hubicka  <jh@suse.cz>
+
+       * i386.md (type): Add new SSE/MMX subtypes, remove usused fop1.
+       (mode): Add vector modes
+       (i387): Kill attribute.
+       (unit): New attribute.
+       (length_immediate): Grok new types.
+       (prefix_data16, prefix_rep, prefix_0f): Fix for SSE/MMX.
+       (modrm): Use "unit".
+       (memory): Handle MMX/SSE properly.
+       (scheduling descriptions): Kill uses of fop1.
+       (sse, mmx, fp patterns): Set type and mode properly.
+
 Tue Apr 30 09:31:59 2002  Jeffrey A Law  (law@cygnus.com)
 
        * pa.c (override_options): Default to PA8000 scheduling.
index bd2dfbf..e99fe3e 100644 (file)
 ;; A basic instruction type.  Refinements due to arguments to be
 ;; provided in other attributes.
 (define_attr "type"
-  "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"
+  "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,sseadd,ssemul,ssediv,ssemov,ssecmp,ssecvt,sselog,sseiadd,sseishft,sseimul,mmx,mmxmov,mmxadd,mmxshft,mmxcmp,mmxcvt,mmxmul,fistp"
   (const_string "other"))
 
 ;; Main data type used by the insn
-(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
+(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI,V4SF,V2DF,V2SF"
   (const_string "unknown"))
 
-;; Set for i387 operations.
-(define_attr "i387" ""
-  (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
-    (const_int 1)
-    (const_int 0)))
+;; The CPU unit operations uses.
+(define_attr "unit" "integer,i387,sse,mmx,unknown"
+  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
+          (const_string "i387")
+        (eq_attr "type" "sse,sseadd,ssemul,ssediv,ssemov,ssecmp,ssecvt,sselog,sseiadd,sseishft,sseimul")
+          (const_string "sse")
+        (eq_attr "type" "mmx,mmxmov,mmxadd,mmxshft,mmxcmp,mmxcvt,mmxmul")
+          (const_string "mmx")]
+        (const_string "integer")))
 
 ;; The (bounding maximum) length of an instruction immediate.
 (define_attr "length_immediate" ""
-  (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
+  (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv")
           (const_int 0)
-        (eq_attr "i387" "1")
+        (eq_attr "unit" "i387,sse,mmx")
           (const_int 0)
         (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
           (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
 
 ;; Set when length prefix is used.
 (define_attr "prefix_data16" ""
-  (if_then_else (eq_attr "mode" "HI")
+  (if_then_else (ior (eq_attr "mode" "HI")
+                    (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
     (const_int 1)
     (const_int 0)))
 
 ;; Set when string REP prefix is used.
-(define_attr "prefix_rep" "" (const_int 0))
+(define_attr "prefix_rep" "" 
+  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
+    (const_int 1)
+    (const_int 0)))
 
 ;; Set when 0f opcode prefix is used.
 (define_attr "prefix_0f" ""
-  (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
+  (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,sseadd,ssemul,ssediv,ssemov,ssecmp,ssecvt,sselog,sseiadd,sseishft,sseimul,mmx,mmxmov,mmxadd,mmxshft,mmxcmp,mmxcvt,mmxmul")
     (const_int 1)
     (const_int 0)))
 
 (define_attr "modrm" ""
   (cond [(eq_attr "type" "str,cld")
           (const_int 0)
-        (eq_attr "i387" "1")
+        (eq_attr "unit" "i387")
           (const_int 0)
          (and (eq_attr "type" "incdec")
              (ior (match_operand:SI 1 "register_operand" "")
 (define_attr "length" ""
   (cond [(eq_attr "type" "other,multi,fistp")
           (const_int 16)
-        ]
+        (eq_attr "unit" "i387")
+          (plus (const_int 2)
+                (plus (attr "prefix_data16")
+                      (attr "length_address")))]
         (plus (plus (attr "modrm")
                     (plus (attr "prefix_0f")
-                          (plus (attr "i387")
-                                (const_int 1))))
+                          (const_int 1)))
               (plus (attr "prefix_rep")
                     (plus (attr "prefix_data16")
                           (plus (attr "length_immediate")
           (const_string "store")
         (match_operand 1 "memory_operand" "")
           (const_string "load")
-        (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
+        (and (eq_attr "type" "!icmp,test,alu1,negnot,fsgn,imov,imovx,fmov,fcmp,sse,mmx,ssemov,mmxmov,ssecvt,mmxcvt")
              (match_operand 2 "memory_operand" ""))
           (const_string "load")
         (and (eq_attr "type" "icmov")
 ; integer instructions, because of the inpaired fxch instruction.
 (define_function_unit "pent_np" 1 0
   (and (eq_attr "cpu" "pentium")
-       (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
+       (eq_attr "type" "fmov,fop,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
   2 2
-  [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
+  [(eq_attr "type" "!fmov,fop,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
 
 (define_function_unit "fpu" 1 0
   (and (eq_attr "cpu" "pentium")
 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
 (define_function_unit "fpu" 1 0
   (and (eq_attr "cpu" "pentium")
-       (eq_attr "type" "fop,fop1,fistp"))
+       (eq_attr "type" "fop,fistp"))
   3 1)
 
 ; Multiplication takes 3 cycles and is only half pipelined.
 
 (define_function_unit "ppro_p0" 1 0
   (and (eq_attr "cpu" "pentiumpro")
-       (eq_attr "type" "fop,fop1,fsgn,fistp"))
+       (eq_attr "type" "fop,fsgn,fistp"))
   3 1)
 
 (define_function_unit "ppro_p0" 1 0
 
 (define_function_unit "fpu" 1 0
   (and (eq_attr "cpu" "pentiumpro")
-       (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
+       (eq_attr "type" "fop,fsgn,fmov,fcmp,fcmov,fistp"))
   1 1)
 
 (define_function_unit "fpu" 1 0
 
 (define_function_unit "k6_fpu" 1 1
   (and (eq_attr "cpu" "k6")
-       (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
+       (eq_attr "type" "fop,fmov,fcmp,fistp"))
   2 2)
 
 (define_function_unit "k6_fpu" 1 1
   42 42)
 
 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
-  (cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
+  (cond [(eq_attr "type" "fop,fcmp,fistp")
           (const_string "add")
          (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
           (const_string "mul")
 
 (define_function_unit "athlon_fp" 3 0
   (and (eq_attr "cpu" "athlon")
-       (eq_attr "type" "fop,fop1,fmul,fistp"))
+       (eq_attr "type" "fop,fmul,fistp"))
   4 1)
 
 ;; XFmode loads are slow.
   "fnstsw\t%0"
   [(set_attr "length" "2")
    (set_attr "mode" "SI")
-   (set_attr "i387" "1")
+   (set_attr "unit" "i387")
    (set_attr "ppro_uops" "few")])
 
 ;; FP compares, step 3
    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
   "* return output_fp_compare (insn, operands, 1, 0);"
-  [(set_attr "type" "fcmp,sse")
+  [(set_attr "type" "fcmp,ssecmp")
    (set_attr "mode" "unknownfp")
    (set_attr "athlon_decode" "vector")])
 
   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
   "* return output_fp_compare (insn, operands, 1, 0);"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecmp")
    (set_attr "mode" "unknownfp")
    (set_attr "athlon_decode" "vector")])
 
    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
   "* return output_fp_compare (insn, operands, 1, 1);"
-  [(set_attr "type" "fcmp,sse")
+  [(set_attr "type" "fcmp,ssecmp")
    (set_attr "mode" "unknownfp")
    (set_attr "athlon_decode" "vector")])
 
   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
   "* return output_fp_compare (insn, operands, 1, 1);"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecmp")
    (set_attr "mode" "unknownfp")
    (set_attr "athlon_decode" "vector")])
 \f
 }
   [(set (attr "type")
      (cond [(eq_attr "alternative" "4,5,6")
-             (const_string "mmx")
+             (const_string "mmxmov")
            (eq_attr "alternative" "7,8,9")
-             (const_string "sse")
+             (const_string "ssemov")
            (and (ne (symbol_ref "flag_pic") (const_int 0))
                 (match_operand:SI 1 "symbolic_operand" ""))
              (const_string "lea")
    movq\t{%1, %0|%0, %1}
    movdqa\t{%1, %0|%0, %1}
    movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
+  [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
 
 (define_split
 }
   [(set (attr "type")
      (cond [(eq_attr "alternative" "5,6")
-             (const_string "mmx")
+             (const_string "mmxmov")
            (eq_attr "alternative" "7,8")
-             (const_string "sse")
+             (const_string "ssemov")
            (eq_attr "alternative" "4")
              (const_string "multi")
            (and (ne (symbol_ref "flag_pic") (const_int 0))
       abort();
     }
 }
-  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx,mmx")
+  [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
    (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
 
 (define_insn "*swapsf"
       abort();
     }
 }
-  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
+  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
    (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
 
 (define_insn "*movdf_integer"
       abort();
     }
 }
-  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
+  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
    (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
 
 (define_split
       abort ();
     }
 }
-  [(set_attr "type" "fmov,fmov,sse")
+  [(set_attr "type" "fmov,fmov,ssecvt")
    (set_attr "mode" "SF,XF,DF")])
 
 (define_insn "*extendsfdf2_1_sse_only"
   "!TARGET_80387 && TARGET_SSE2
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "cvtss2sd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecvt")
    (set_attr "mode" "DF")])
 
 (define_expand "extendsfxf2"
       abort ();
     }
 }
-  [(set_attr "type" "fmov,multi,multi,multi,sse")
+  [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
    (set_attr "mode" "SF,SF,SF,SF,DF")])
 
 (define_insn "*truncdfsf2_2"
       abort ();
     }
 }
-  [(set_attr "type" "sse,fmov")
+  [(set_attr "type" "ssecvt,fmov")
    (set_attr "mode" "DF,SF")])
 
 (define_insn "truncdfsf2_3"
         (match_operand:DF 1 "nonimmediate_operand" "mY")))]
   "!TARGET_80387 && TARGET_SSE2"
   "cvtsd2ss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecvt")
    (set_attr "mode" "DF")])
 
 (define_split
        (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
   "TARGET_64BIT && TARGET_SSE"
   "cvttss2si{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")])
 
 (define_insn "fix_truncdfdi_sse"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
   "TARGET_64BIT && TARGET_SSE2"
   "cvttsd2si{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")])
 
 ;; Signed conversion to SImode.
 
        (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "cvttss2si\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")])
 
 (define_insn "fix_truncdfsi_sse"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
   "TARGET_SSE2"
   "cvttsd2si\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")])
 
 (define_split 
   [(set (match_operand:SI 0 "register_operand" "")
   "fnstcw\t%0"
   [(set_attr "length" "2")
    (set_attr "mode" "HI")
-   (set_attr "i387" "1")
+   (set_attr "unit" "i387")
    (set_attr "ppro_uops" "few")])
 
 (define_insn "x86_fldcw_1"
   "fldcw\t%0"
   [(set_attr "length" "2")
    (set_attr "mode" "HI")
-   (set_attr "i387" "1")
+   (set_attr "unit" "i387")
    (set_attr "athlon_decode" "vector")
    (set_attr "ppro_uops" "few")])
 \f
    fild%z1\t%1
    #
    cvtsi2ss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "fmov,multi,sse")
+  [(set_attr "type" "fmov,multi,ssecvt")
    (set_attr "mode" "SF")
    (set_attr "fp_int_src" "true")])
 
        (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
   "TARGET_SSE"
   "cvtsi2ss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecvt")
    (set_attr "mode" "SF")
    (set_attr "fp_int_src" "true")])
 
    fild%z1\t%1
    #
    cvtsi2ss{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "fmov,multi,sse")
+  [(set_attr "type" "fmov,multi,ssecvt")
    (set_attr "mode" "SF")
    (set_attr "fp_int_src" "true")])
 
        (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
   "TARGET_64BIT && TARGET_SSE"
   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecvt")
    (set_attr "mode" "SF")
    (set_attr "fp_int_src" "true")])
 
    fild%z1\t%1
    #
    cvtsi2sd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "fmov,multi,sse")
+  [(set_attr "type" "fmov,multi,ssecvt")
    (set_attr "mode" "DF")
    (set_attr "fp_int_src" "true")])
 
        (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
   "TARGET_SSE2"
   "cvtsi2sd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecvt")
    (set_attr "mode" "DF")
    (set_attr "fp_int_src" "true")])
 
    fild%z1\t%1
    #
    cvtsi2sd{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "fmov,multi,sse")
+  [(set_attr "type" "fmov,multi,ssecvt")
    (set_attr "mode" "DF")
    (set_attr "fp_int_src" "true")])
 
        (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
   "TARGET_SSE2"
   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecvt")
    (set_attr "mode" "DF")
    (set_attr "fp_int_src" "true")])
 
           (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
   "TARGET_SSE && reload_completed"
   "cmp%D1ss\t{%3, %0|%0, %3}"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecmp")
    (set_attr "mode" "SF")])
 
 (define_insn "*sse_setccdf"
           (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
   "TARGET_SSE2 && reload_completed"
   "cmp%D1sd\t{%3, %0|%0, %3}"
-  [(set_attr "type" "sse")
+  [(set_attr "type" "ssecmp")
    (set_attr "mode" "DF")])
 \f
 ;; Basic conditional jump instructions.
   "* return output_387_binary_op (insn, operands);"
   [(set (attr "type") 
        (if_then_else (eq_attr "alternative" "1")
-           (const_string "sse")
+          (if_then_else (match_operand:SF 3 "mult_operator" "") 
+             (const_string "ssemul")
+             (const_string "sseadd"))
           (if_then_else (match_operand:SF 3 "mult_operator" "") 
              (const_string "fmul")
              (const_string "fop"))))
   "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "* return output_387_binary_op (insn, operands);"
-  [(set_attr "type" "sse")
+  [(set (attr "type") 
+        (if_then_else (match_operand:SF 3 "mult_operator" "") 
+          (const_string "ssemul")
+          (const_string "sseadd")))
    (set_attr "mode" "SF")])
 
 (define_insn "*fop_df_comm_nosse"
   "* return output_387_binary_op (insn, operands);"
   [(set (attr "type") 
        (if_then_else (eq_attr "alternative" "1")
-           (const_string "sse")
+          (if_then_else (match_operand:SF 3 "mult_operator" "") 
+             (const_string "ssemul")
+             (const_string "sseadd"))
           (if_then_else (match_operand:SF 3 "mult_operator" "") 
              (const_string "fmul")
              (const_string "fop"))))
    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "* return output_387_binary_op (insn, operands);"
-  [(set_attr "type" "sse")
+  [(set (attr "type") 
+        (if_then_else (match_operand:SF 3 "mult_operator" "") 
+          (const_string "ssemul")
+          (const_string "sseadd")))
    (set_attr "mode" "DF")])
 
 (define_insn "*fop_xf_comm"
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "* return output_387_binary_op (insn, operands);"
   [(set (attr "type") 
-        (cond [(eq_attr "alternative" "2")
-                 (const_string "sse")
+        (cond [(and (eq_attr "alternative" "2")
+                   (match_operand:SF 3 "mult_operator" ""))
+                 (const_string "ssemul")
+              (and (eq_attr "alternative" "2")
+                   (match_operand:SF 3 "div_operator" ""))
+                 (const_string "ssediv")
+              (eq_attr "alternative" "2")
+                 (const_string "sseadd")
               (match_operand:SF 3 "mult_operator" "") 
                  (const_string "fmul")
                (match_operand:SF 3 "div_operator" "") 
   "TARGET_SSE_MATH
    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
   "* return output_387_binary_op (insn, operands);"
-  [(set_attr "type" "sse")
+  [(set (attr "type") 
+        (cond [(match_operand:SF 3 "mult_operator" "")
+                 (const_string "ssemul")
+              (match_operand:SF 3 "div_operator" "")
+                 (const_string "ssediv")
+              ]
+              (const_string "sseadd")))
    (set_attr "mode" "SF")])
 
 ;; ??? Add SSE splitters for these!
   [(set (attr "type") 
         (cond [(match_operand:DF 3 "mult_operator" "") 
                  (const_string "fmul")
-               (match_operand:DF 3 "div_operator" "") 
+               (match_operand:DF 3 "div_operator" "")
                  (const_string "fdiv")
               ]
               (const_string "fop")))
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "* return output_387_binary_op (insn, operands);"
   [(set (attr "type") 
-        (cond [(eq_attr "alternative" "2")
-                 (const_string "sse")
+        (cond [(and (eq_attr "alternative" "2")
+                   (match_operand:SF 3 "mult_operator" ""))
+                 (const_string "ssemul")
+              (and (eq_attr "alternative" "2")
+                   (match_operand:SF 3 "div_operator" ""))
+                 (const_string "ssediv")
+              (eq_attr "alternative" "2")
+                 (const_string "sseadd")
               (match_operand:DF 3 "mult_operator" "") 
                  (const_string "fmul")
                (match_operand:DF 3 "div_operator" "") 
   "TARGET_SSE2 && TARGET_SSE_MATH
    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
   "* return output_387_binary_op (insn, operands);"
-  [(set_attr "type" "sse")])
+  [(set_attr "mode" "DF")
+   (set (attr "type") 
+        (cond [(match_operand:SF 3 "mult_operator" "")
+                 (const_string "ssemul")
+              (match_operand:SF 3 "div_operator" "")
+                 (const_string "ssediv")
+              ]
+              (const_string "sseadd")))])
 
 ;; ??? Add SSE splitters for these!
 (define_insn "*fop_df_2"
   "TARGET_SSE"
   ;; @@@ let's try to use movaps here.
   "movaps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "movv4si_internal"
   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
   "TARGET_SSE"
   ;; @@@ let's try to use movaps here.
   "movaps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "movv8qi_internal"
   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
        (match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
   "TARGET_MMX"
   "movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxmov")
+   (set_attr "mode" "DI")])
 
 (define_insn "movv4hi_internal"
   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
        (match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
   "TARGET_MMX"
   "movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxmov")
+   (set_attr "mode" "DI")])
 
 (define_insn "movv2si_internal"
   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
        (match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
   "TARGET_MMX"
   "movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "movv2sf_internal"
   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
         (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
   "TARGET_3DNOW"
   "movq\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_expand "movti"
   [(set (match_operand:TI 0 "general_operand" "")
   "TARGET_SSE2"
   ;; @@@ let's try to use movaps here.
   "movapd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "movv8hi_internal"
   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
   "TARGET_SSE2"
   ;; @@@ let's try to use movaps here.
   "movaps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "movv16qi_internal"
   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
   "TARGET_SSE2"
   ;; @@@ let's try to use movaps here.
   "movaps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "V4SF")])
 
 (define_expand "movv2df"
   [(set (match_operand:V2DF 0 "general_operand" "")
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
    (set (mem:TI (reg:SI 7)) (match_dup 1))]
   ""
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "multi")])
 
 (define_insn_and_split "*pushv2df"
   [(set (match_operand:V2DF 0 "push_operand" "=<")
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
    (set (mem:V2DF (reg:SI 7)) (match_dup 1))]
   ""
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "multi")])
 
 (define_insn_and_split "*pushv8hi"
   [(set (match_operand:V8HI 0 "push_operand" "=<")
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
    (set (mem:V8HI (reg:SI 7)) (match_dup 1))]
   ""
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "multi")])
 
 (define_insn_and_split "*pushv16qi"
   [(set (match_operand:V16QI 0 "push_operand" "=<")
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
    (set (mem:V16QI (reg:SI 7)) (match_dup 1))]
   ""
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "multi")])
 
 (define_insn_and_split "*pushv4sf"
   [(set (match_operand:V4SF 0 "push_operand" "=<")
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
    (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
   ""
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "multi")])
 
 (define_insn_and_split "*pushv4si"
   [(set (match_operand:V4SI 0 "push_operand" "=<")
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
    (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
   ""
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "multi")])
 
 (define_insn_and_split "*pushv2si"
   [(set (match_operand:V2SI 0 "push_operand" "=<")
    xorps\t%0, %0
    movaps\t{%1, %0|%0, %1}
    movaps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov,ssemov,ssemov")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "*movti_rex64"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
    xorps\t%0, %0
    movaps\\t{%1, %0|%0, %1}
    movaps\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "*,*,sse,sse,sse")
-   (set_attr "mode" "TI")])
+  [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
+   (set_attr "mode" "V4SF")])
 
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
   "@
    movaps\t{%1, %0|%0, %1}
    movaps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov,ssemov")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_movups"
   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
   "@
    movups\t{%1, %0|%0, %1}
    movups\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt,ssecvt")
+   (set_attr "mode" "V4SF")])
 
 
 ;; SSE Strange Moves.
        (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
   "TARGET_SSE"
   "movmskps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "mmx_pmovmskb"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pmovmskb\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
+
 
 (define_insn "mmx_maskmovq"
   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
   ;; @@@ check ordering of operands in intel/nonintel syntax
   "maskmovq\t{%2, %1|%1, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_maskmovq_rex"
   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
   ;; @@@ check ordering of operands in intel/nonintel syntax
   "maskmovq\t{%2, %1|%1, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "sse_movntv4sf"
   [(set (match_operand:V4SF 0 "memory_operand" "=m")
        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
   "TARGET_SSE"
   "movntps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_movntdi"
   [(set (match_operand:DI 0 "memory_operand" "=m")
        (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "movntq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxmov")
+   (set_attr "mode" "DI")])
 
 (define_insn "sse_movhlps"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 3)))]
   "TARGET_SSE"
   "movhlps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_movlhps"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 12)))]
   "TARGET_SSE"
   "movlhps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_movhps"
   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
   "TARGET_SSE
    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
   "movhps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_movlps"
   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
   "TARGET_SSE
    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
   "movlps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_loadss"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "movss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "SF")])
 
 (define_insn "sse_movss"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "movss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "SF")])
 
 (define_insn "sse_storess"
   [(set (match_operand:SF 0 "memory_operand" "=m")
         (parallel [(const_int 0)])))]
   "TARGET_SSE"
   "movss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "SF")])
 
 (define_insn "sse_shufps"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
   "TARGET_SSE"
   ;; @@@ check operand order for intel/nonintel syntax
   "shufps\t{%3, %2, %0|%0, %2, %3}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 
 ;; SSE arithmetic
                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "addps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmaddv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "addss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "SF")])
 
 (define_insn "subv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "subps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmsubv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "subss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "SF")])
 
 (define_insn "mulv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "mulps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemul")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmmulv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "mulss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemul")
+   (set_attr "mode" "SF")])
 
 (define_insn "divv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
                  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "divps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssediv")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmdivv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "divss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssediv")
+   (set_attr "mode" "SF")])
 
 
 ;; SSE square root/reciprocal
         [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42))]
   "TARGET_SSE"
   "rcpps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmrcpv4sf2"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "rcpss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "SF")])
 
 (define_insn "rsqrtv4sf2"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43))]
   "TARGET_SSE"
   "rsqrtps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmrsqrtv4sf2"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "rsqrtss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "SF")])
 
 (define_insn "sqrtv4sf2"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "sqrtps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmsqrtv4sf2"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "sqrtss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "SF")])
 
 ;; SSE logical operations.
 
                (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
   "TARGET_SSE2"
   "andpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "*sse_andti3_df_2"
   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
                (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
   "TARGET_SSE2"
   "andpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "*sse_andti3_sf_1"
   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
                (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
   "TARGET_SSE"
   "andps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "*sse_andti3_sf_2"
   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
                (match_operand:TI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "andps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_andti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
   "TARGET_SSE && !TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "andps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse2_andti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
   "TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "pand\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "TI")])
 
 (define_insn "*sse_nandti3_df"
   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
                (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
   "TARGET_SSE2"
   "andnpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "*sse_nandti3_sf"
   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
                (match_operand:TI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "andnps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_nandti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
                (match_operand:TI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE && !TARGET_SSE2"
   "andnps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse2_nandti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
                (match_operand:TI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pandn\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")])
 
 (define_insn "*sse_iorti3_df_1"
   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
                (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
   "TARGET_SSE2"
   "orpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "*sse_iorti3_df_2"
   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
                (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
   "TARGET_SSE2"
   "orpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "*sse_iorti3_sf_1"
   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
                (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
   "TARGET_SSE"
   "orps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "*sse_iorti3_sf_2"
   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
                (match_operand:TI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "orps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_iorti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
   "TARGET_SSE && !TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "orps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse2_iorti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
   "TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "por\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "TI")])
 
 (define_insn "*sse_xorti3_df_1"
   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
                (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
   "TARGET_SSE2"
   "xorpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "*sse_xorti3_df_2"
   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
                (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
   "TARGET_SSE2"
   "xorpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "*sse_xorti3_sf_1"
   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
                (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
   "TARGET_SSE"
   "xorps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "*sse_xorti3_sf_2"
   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
                (match_operand:TI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "xorps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_xorti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
   "TARGET_SSE && !TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "xorps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse2_xorti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
   "TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "pxor\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "TI")])
 
 ;; Use xor, but don't show input operands so they aren't live before
 ;; this insn.
         (unspec:V4SF [(const_int 0)] 45))]
   "TARGET_SSE"
   "xorps\t{%0, %0|%0, %0}"
-  [(set_attr "type" "sse")
-   (set_attr "memory" "none")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V4SF")])
 
 ;; SSE mask-generating compares
 
                 (match_operand:V4SF 2 "register_operand" "x")]))]
   "TARGET_SSE"
   "cmp%D3ps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "maskncmpv4sf3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
   else
     return "cmpn%D3ps\t{%2, %0|%0, %2}";
 }
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmmaskcmpv4sf3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "cmp%D3ss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "SF")])
 
 (define_insn "vmmaskncmpv4sf3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
   else
     return "cmpn%D3ss\t{%2, %0|%0, %2}";
 }
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "SF")])
 
 (define_insn "sse_comi"
   [(set (reg:CCFP 17)
                          (parallel [(const_int 0)]))]))]
   "TARGET_SSE"
   "comiss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "SF")])
 
 (define_insn "sse_ucomi"
   [(set (reg:CCFPU 17)
                          (parallel [(const_int 0)]))]))]
   "TARGET_SSE"
   "ucomiss\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "SF")])
 
 
 ;; SSE unpack
         (const_int 5)))]
   "TARGET_SSE"
   "unpckhps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "sse_unpcklps"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 5)))]
   "TARGET_SSE"
   "unpcklps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 
 ;; SSE min/max
                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "maxps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmsmaxv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "maxss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "SF")])
 
 (define_insn "sminv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "minps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "vmsminv4sf3"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE"
   "minss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "SF")])
 
 
 ;; SSE <-> integer/MMX conversions
         (const_int 12)))]
   "TARGET_SSE"
   "cvtpi2ps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "cvtps2pi"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
         (parallel [(const_int 0) (const_int 1)])))]
   "TARGET_SSE"
   "cvtps2pi\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "cvttps2pi"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
         (parallel [(const_int 0) (const_int 1)])))]
   "TARGET_SSE"
   "cvttps2pi\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "SF")])
 
 (define_insn "cvtsi2ss"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
         (const_int 14)))]
   "TARGET_SSE"
   "cvtsi2ss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "SF")])
 
 (define_insn "cvtss2si"
   [(set (match_operand:SI 0 "register_operand" "=r")
         (parallel [(const_int 0)])))]
   "TARGET_SSE"
   "cvtss2si\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "SF")])
 
 (define_insn "cvttss2si"
   [(set (match_operand:SI 0 "register_operand" "=r")
         (parallel [(const_int 0)])))]
   "TARGET_SSE"
   "cvttss2si\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "SF")])
 
 
 ;; MMX insns
                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "paddb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "addv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "paddw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "addv2si3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "paddd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "ssaddv8qi3"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
                      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "paddsb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "ssaddv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "paddsw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "usaddv8qi3"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
                      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "paddusb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "usaddv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "paddusw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "subv8qi3"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "psubb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "subv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "psubw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "subv2si3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "psubd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "sssubv8qi3"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "psubsb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "sssubv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "psubsw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "ussubv8qi3"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "psubusb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "ussubv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "psubusw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "mulv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "pmullw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxmul")
+   (set_attr "mode" "DI")])
 
 (define_insn "smulv4hi3_highpart"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
          (const_int 16))))]
   "TARGET_MMX"
   "pmulhw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxmul")
+   (set_attr "mode" "DI")])
 
 (define_insn "umulv4hi3_highpart"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
          (const_int 16))))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pmulhuw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxmul")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_pmaddwd"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                                                        (const_int 3)]))))))]
   "TARGET_MMX"
   "pmaddwd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxmul")
+   (set_attr "mode" "DI")])
 
 
 ;; MMX logical operations
                  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
   "TARGET_MMX"
   "por\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_xordi3"
   [(set (match_operand:DI 0 "register_operand" "=y")
                  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
   "TARGET_MMX"
   "pxor\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")
    (set_attr "memory" "none")])
 
 ;; Same as pxor, but don't show input operands so that we don't think
         (unspec:DI [(const_int 0)] 45))]
   "TARGET_MMX"
   "pxor\t{%0, %0|%0, %0}"
-  [(set_attr "type" "mmx")
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")
    (set_attr "memory" "none")])
 
 (define_insn "mmx_anddi3"
                  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
   "TARGET_MMX"
   "pand\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_nanddi3"
   [(set (match_operand:DI 0 "register_operand" "=y")
                          (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
   "TARGET_MMX"
   "pandn\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 
 ;; MMX unsigned averages/sum of absolute differences
         (const_int 1)))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pavgb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_uavgv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
         (const_int 1)))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pavgw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_psadbw"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
                              (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "psadbw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 
 ;; MMX insert/extract/shuffle
                        (match_operand:SI 3 "immediate_operand" "i")))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_pextrw"
   [(set (match_operand:SI 0 "register_operand" "=r")
                                        [(match_operand:SI 2 "immediate_operand" "i")]))))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pextrw\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_pshufw"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                      (match_operand:SI 2 "immediate_operand" "i")] 41))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pshufw\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 
 ;; MMX mask-generating comparisons
                 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "pcmpeqb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcmp")
+   (set_attr "mode" "DI")])
 
 (define_insn "eqv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "pcmpeqw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcmp")
+   (set_attr "mode" "DI")])
 
 (define_insn "eqv2si3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "pcmpeqd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcmp")
+   (set_attr "mode" "DI")])
 
 (define_insn "gtv8qi3"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
                 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "pcmpgtb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcmp")
+   (set_attr "mode" "DI")])
 
 (define_insn "gtv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "pcmpgtw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcmp")
+   (set_attr "mode" "DI")])
 
 (define_insn "gtv2si3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX"
   "pcmpgtd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcmp")
+   (set_attr "mode" "DI")])
 
 
 ;; MMX max/min insns
                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pmaxub\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "smaxv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pmaxsw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "uminv8qi3"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pminub\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 (define_insn "sminv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pminsw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "DI")])
 
 
 ;; MMX shifts
                       (match_operand:DI 2 "nonmemory_operand" "yi")))]
   "TARGET_MMX"
   "psraw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "ashrv2si3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                       (match_operand:DI 2 "nonmemory_operand" "yi")))]
   "TARGET_MMX"
   "psrad\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "lshrv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                       (match_operand:DI 2 "nonmemory_operand" "yi")))]
   "TARGET_MMX"
   "psrlw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "lshrv2si3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                       (match_operand:DI 2 "nonmemory_operand" "yi")))]
   "TARGET_MMX"
   "psrld\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 ;; See logical MMX insns.
 (define_insn "mmx_lshrdi3"
                       (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
   "TARGET_MMX"
   "psrlq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "ashlv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
                       (match_operand:DI 2 "nonmemory_operand" "yi")))]
   "TARGET_MMX"
   "psllw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "ashlv2si3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                       (match_operand:DI 2 "nonmemory_operand" "yi")))]
   "TARGET_MMX"
   "pslld\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 ;; See logical MMX insns.
 (define_insn "mmx_ashldi3"
                     (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
   "TARGET_MMX"
   "psllq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 
 ;; MMX pack/unpack insns.
         (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
   "TARGET_MMX"
   "packsswb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_packssdw"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
         (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
   "TARGET_MMX"
   "packssdw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_packuswb"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
         (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
   "TARGET_MMX"
   "packuswb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_punpckhbw"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
         (const_int 85)))]
   "TARGET_MMX"
   "punpckhbw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_punpckhwd"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
         (const_int 5)))]
   "TARGET_MMX"
   "punpckhwd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_punpckhdq"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
         (const_int 1)))]
   "TARGET_MMX"
   "punpckhdq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_punpcklbw"
   [(set (match_operand:V8QI 0 "register_operand" "=y")
         (const_int 85)))]
   "TARGET_MMX"
   "punpcklbw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_punpcklwd"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
         (const_int 5)))]
   "TARGET_MMX"
   "punpcklwd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 (define_insn "mmx_punpckldq"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
         (const_int 1)))]
   "TARGET_MMX"
   "punpckldq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "DI")])
 
 
 ;; Miscellaneous stuff
                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
   "TARGET_3DNOW"
   "pfadd\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "subv2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
   "TARGET_3DNOW"
   "pfsub\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "subrv2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                     (match_operand:V2SF 1 "register_operand" "0")))]
   "TARGET_3DNOW"
   "pfsubr\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "gtv2sf3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
  "TARGET_3DNOW"
   "pfcmpgt\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcmp")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "gev2sf3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
   "TARGET_3DNOW"
   "pfcmpge\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcmp")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "eqv2sf3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
   "TARGET_3DNOW"
   "pfcmpeq\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcmp")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "pfmaxv2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
   "TARGET_3DNOW"
   "pfmax\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "pfminv2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
   "TARGET_3DNOW"
   "pfmin\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "mulv2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
   "TARGET_3DNOW"
   "pfmul\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxmul")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "femms"
   [(unspec_volatile [(const_int 0)] 46)
        (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
   "TARGET_3DNOW"
   "pf2id\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "pf2iw"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
              (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
   "TARGET_3DNOW_A"
   "pf2iw\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "pfacc"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                             (parallel [(const_int 1)])))))]
   "TARGET_3DNOW"
   "pfacc\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "pfnacc"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                             (parallel [(const_int 1)])))))]
   "TARGET_3DNOW_A"
   "pfnacc\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "pfpnacc"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                             (parallel [(const_int 1)])))))]
   "TARGET_3DNOW_A"
   "pfpnacc\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxadd")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "pi2fw"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                                   (parallel [(const_int  1)])))))))]
   "TARGET_3DNOW_A"
   "pi2fw\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "V2SF")])
 
 (define_insn "floatv2si2"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
        (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
   "TARGET_3DNOW"
   "pi2fd\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "V2SF")])
 
 ;; This insn is identical to pavgb in operation, but the opcode is
 ;; different.  To avoid accidentally matching pavgb, use an unspec.
            (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
   "TARGET_3DNOW"
   "pavgusb\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxshft")
+   (set_attr "mode" "TI")])
 
 ;; 3DNow reciprical and sqrt
  
         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
   "TARGET_3DNOW"
   "pfrcp\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmx")
+   (set_attr "mode" "TI")])
 
 (define_insn "pfrcpit1v2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
   "TARGET_3DNOW"
   "pfrcpit1\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmx")
+   (set_attr "mode" "TI")])
 
 (define_insn "pfrcpit2v2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
   "TARGET_3DNOW"
   "pfrcpit2\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmx")
+   (set_attr "mode" "TI")])
 
 (define_insn "pfrsqrtv2sf2"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
   "TARGET_3DNOW"
-   "pfrsqrt\\t{%1, %0|%0, %1}"
-   [(set_attr "type" "mmx")])
+  "pfrsqrt\\t{%1, %0|%0, %1}"
+  [(set_attr "type" "mmx")
+   (set_attr "mode" "TI")])
                
 (define_insn "pfrsqit1v2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
   "TARGET_3DNOW"
   "pfrsqit1\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmx")
+   (set_attr "mode" "TI")])
 
 (define_insn "pmulhrwv4hi3"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
              (const_int 16))))]
   "TARGET_3DNOW"
   "pmulhrw\\t{%2, %0|%0, %2}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxmul")
+   (set_attr "mode" "TI")])
 
 (define_insn "pswapdv2si2"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
                         (parallel [(const_int 1) (const_int 0)])))]
   "TARGET_3DNOW_A"
   "pswapd\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "pswapdv2sf2"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
                         (parallel [(const_int 1) (const_int 0)])))]
   "TARGET_3DNOW_A"
   "pswapd\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmxcvt")
+   (set_attr "mode" "TI")])
 
 (define_expand "prefetch"
   [(prefetch (match_operand:SI 0 "address_operand" "")
 
   return patterns[locality];  
 }
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "memory" "none")])
 
 (define_insn "*prefetch_3dnow"
   [(prefetch (match_operand:SI 0 "address_operand" "p")
   else
     return "prefetchw\t%a0";
 }
-  [(set_attr "type" "mmx")])
+  [(set_attr "type" "mmx")
+   (set_attr "memory" "none")])
 
 ;; SSE2 support
 
                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "addpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "vmaddv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                        (const_int 1)))]
   "TARGET_SSE2"
   "addsd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "DF")])
 
 (define_insn "subv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "subpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "vmsubv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                        (const_int 1)))]
   "TARGET_SSE2"
   "subsd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "DF")])
 
 (define_insn "mulv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "mulpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemul")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "vmmulv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                        (const_int 1)))]
   "TARGET_SSE2"
   "mulsd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemul")
+   (set_attr "mode" "DF")])
 
 (define_insn "divv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "divpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssediv")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "vmdivv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                        (const_int 1)))]
   "TARGET_SSE2"
   "divsd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssediv")
+   (set_attr "mode" "DF")])
 
 ;; SSE min/max
 
                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "maxpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "vmsmaxv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                        (const_int 1)))]
   "TARGET_SSE2"
   "maxsd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "DF")])
 
 (define_insn "sminv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "minpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "vmsminv2df3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                        (const_int 1)))]
   "TARGET_SSE2"
   "minsd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseadd")
+   (set_attr "mode" "DF")])
 
 (define_insn "sse2_anddf3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                             (subreg:TI (match_operand:TI 2 "nonimmediate_operand" "xm") 0)) 0))]
   "TARGET_SSE2"
   "andpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_nanddf3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                             (subreg:TI (match_operand:TI 2 "nonimmediate_operand" "xm") 0)) 0))]
   "TARGET_SSE2"
   "andnpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_iordf3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                             (subreg:TI (match_operand:TI 2 "nonimmediate_operand" "xm") 0)) 0))]
   "TARGET_SSE2"
   "orpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_xordf3"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                             (subreg:TI (match_operand:TI 2 "nonimmediate_operand" "xm") 0)) 0))]
   "TARGET_SSE2"
   "xorpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sselog")
+   (set_attr "mode" "V2DF")])
 ;; SSE2 square root.  There doesn't appear to be an extension for the
 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
 
         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
   "TARGET_SSE2"
   "sqrtpd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "vmsqrtv2df2"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                        (const_int 1)))]
   "TARGET_SSE2"
   "sqrtsd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "mode" "SF")])
 
 ;; SSE mask-generating compares
 
                              (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
   "TARGET_SSE2"
   "cmp%D3pd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "maskncmpv2df3"
   [(set (match_operand:V2DI 0 "register_operand" "=x")
                               (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
   "TARGET_SSE2"
   "cmpn%D3pd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "vmmaskcmpv2df3"
   [(set (match_operand:V2DI 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE2"
   "cmp%D3sd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "DF")])
 
 (define_insn "vmmaskncmpv2df3"
   [(set (match_operand:V2DI 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE2"
   "cmp%D3sd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "DF")])
 
 (define_insn "sse2_comi"
   [(set (reg:CCFP 17)
                          (parallel [(const_int 0)]))]))]
   "TARGET_SSE2"
   "comisd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "DF")])
 
 (define_insn "sse2_ucomi"
   [(set (reg:CCFPU 17)
                          (parallel [(const_int 0)]))]))]
   "TARGET_SSE2"
   "ucomisd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "DF")])
 
 ;; SSE Strange Moves.
 
        (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")] 33))]
   "TARGET_SSE2"
   "movmskpd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_pmovmskb"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")] 33))]
   "TARGET_SSE2"
   "pmovmskb\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_maskmovdqu"
   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
   "TARGET_SSE2"
   ;; @@@ check ordering of operands in intel/nonintel syntax
   "maskmovdqu\t{%2, %1|%1, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_movntv2df"
   [(set (match_operand:V2DF 0 "memory_operand" "=m")
        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")] 34))]
   "TARGET_SSE2"
   "movntpd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_movntti"
   [(set (match_operand:TI 0 "memory_operand" "=m")
        (unspec:TI [(match_operand:TI 1 "register_operand" "x")] 34))]
   "TARGET_SSE2"
   "movntdq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_movntsi"
   [(set (match_operand:SI 0 "memory_operand" "=m")
        (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 34))]
   "TARGET_SSE2"
   "movnti\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 ;; SSE <-> integer/MMX conversions
 
        (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "cvtdq2ps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "cvtps2dq"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
        (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "cvtps2dq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "cvttps2dq"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
        (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30))]
   "TARGET_SSE2"
   "cvttps2dq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 ;; Conversions between SI and DF
 
                       (const_int 1)]))))]
   "TARGET_SSE2"
   "cvtdq2pd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "cvtpd2dq"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
         (const_vector:V2SI [(const_int 0) (const_int 0)])))]
   "TARGET_SSE2"
   "cvtpd2dq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "cvttpd2dq"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
         (const_vector:V2SI [(const_int 0) (const_int 0)])))]
   "TARGET_SSE2"
   "cvttpd2dq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "cvtpd2pi"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
        (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "cvtpd2pi\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "cvttpd2pi"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
        (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")] 30))]
   "TARGET_SSE2"
   "cvttpd2pi\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "cvtpi2pd"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
        (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
   "TARGET_SSE2"
   "cvtpi2pd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 ;; Conversions between SI and DF
 
                               (parallel [(const_int 0)]))))]
   "TARGET_SSE2"
   "cvtsd2si\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "SI")])
 
 (define_insn "cvttsd2si"
   [(set (match_operand:SI 0 "register_operand" "=r")
                                   (parallel [(const_int 0)]))] 30))]
   "TARGET_SSE2"
   "cvttsd2si\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "SI")])
 
 (define_insn "cvtsi2sd"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                        (const_int 2)))]
   "TARGET_SSE2"
   "cvtsd2si\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "DF")])
 
 ;; Conversions between SF and DF
 
                        (const_int 14)))]
   "TARGET_SSE2"
   "cvtsd2ss\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "SF")])
 
 (define_insn "cvtss2sd"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                        (const_int 2)))]
   "TARGET_SSE2"
   "cvtss2sd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "DF")])
 
 (define_insn "cvtpd2ps"
   [(set (match_operand:V4SF 0 "register_operand" "=x")
            (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
   "TARGET_SSE2"
   "cvtpd2ps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V4SF")])
 
 (define_insn "cvtps2pd"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                                      (const_int 1)]))))]
   "TARGET_SSE2"
   "cvtps2pd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 ;; SSE2 variants of MMX insns
 
                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "paddb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "addv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "paddw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "addv4si3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
                   (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "paddd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "addv2di3"
   [(set (match_operand:V2DI 0 "register_operand" "=x")
                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "paddq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "ssaddv16qi3"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "paddsb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "ssaddv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                      (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "paddsw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "usaddv16qi3"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "paddusb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "usaddv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                      (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "paddusw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "subv16qi3"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "psubb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "subv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "psubw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "subv4si3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "psubd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "subv2di3"
   [(set (match_operand:V2DI 0 "register_operand" "=x")
                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "psubq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "sssubv16qi3"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "psubsb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "sssubv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "psubsw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "ussubv16qi3"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "psubusb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "ussubv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "psubusw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "mulv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pmullw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseimul")
+   (set_attr "mode" "TI")])
 
 (define_insn "smulv8hi3_highpart"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
          (const_int 16))))]
   "TARGET_SSE2"
   "pmulhw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseimul")
+   (set_attr "mode" "TI")])
 
 (define_insn "umulv8hi3_highpart"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
          (const_int 16))))]
   "TARGET_SSE2"
   "pmulhuw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseimul")
+   (set_attr "mode" "TI")])
 
 ;; See the MMX logical operations for the reason for the unspec
 (define_insn "sse2_umulsidi3"
                             (zero_extend:DI (match_operand:DI 2 "nonimmediate_operand" "ym")))] 45))]
   "TARGET_SSE2"
   "pmuludq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseimul")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_umulv2siv2di3"
   [(set (match_operand:V2DI 0 "register_operand" "=y")
                       (parallel [(const_int 0) (const_int 2)])))))]
   "TARGET_SSE2"
   "pmuludq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseimul")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_pmaddwd"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
                                                        (const_int 7)]))))))]
   "TARGET_SSE2"
   "pmaddwd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 ;; Same as pxor, but don't show input operands so that we don't think
 ;; they are live.
   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
   "TARGET_SSE2"
   "pxor\t{%0, %0|%0, %0}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 ;; MMX unsigned averages/sum of absolute differences
 
         (const_int 1)))]
   "TARGET_SSE2"
   "pavgb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_uavgv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE2"
   "pavgw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 ;; @@@ this isn't the right representation.
 (define_insn "sse2_psadbw"
                                (match_operand:V16QI 2 "nonimmediate_operand" "ym"))))]
   "TARGET_SSE2"
   "psadbw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 
 ;; MMX insert/extract/shuffle
                        (match_operand:SI 3 "immediate_operand" "i")))]
   "TARGET_SSE2"
   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_pextrw"
   [(set (match_operand:SI 0 "register_operand" "=r")
                          [(match_operand:SI 2 "immediate_operand" "i")]))))]
   "TARGET_SSE2"
   "pextrw\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_pshufd"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
                      (match_operand:SI 2 "immediate_operand" "i")] 41))]
   "TARGET_SSE2"
   "pshufd\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_pshuflw"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                      (match_operand:SI 2 "immediate_operand" "i")] 55))]
   "TARGET_SSE2"
   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_pshufhw"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                      (match_operand:SI 2 "immediate_operand" "i")] 56))]
   "TARGET_SSE2"
   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 ;; MMX mask-generating comparisons
 
                 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pcmpeqb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "TI")])
 
 (define_insn "eqv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pcmpeqw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "TI")])
 
 (define_insn "eqv4si3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pcmpeqd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "TI")])
 
 (define_insn "gtv16qi3"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
                 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pcmpgtb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "TI")])
 
 (define_insn "gtv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pcmpgtw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "TI")])
 
 (define_insn "gtv4si3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pcmpgtd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecmp")
+   (set_attr "mode" "TI")])
 
 
 ;; MMX max/min insns
                   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pmaxub\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "smaxv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pmaxsw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "uminv16qi3"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
                   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pminub\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 (define_insn "sminv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "pminsw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseiadd")
+   (set_attr "mode" "TI")])
 
 
 ;; MMX shifts
                       (match_operand:TI 2 "nonmemory_operand" "xi")))]
   "TARGET_SSE2"
   "psraw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 (define_insn "ashrv4si3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
                       (match_operand:TI 2 "nonmemory_operand" "xi")))]
   "TARGET_SSE2"
   "psrad\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 (define_insn "lshrv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                       (match_operand:TI 2 "nonmemory_operand" "xi")))]
   "TARGET_SSE2"
   "psrlw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 (define_insn "lshrv4si3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
                       (match_operand:TI 2 "nonmemory_operand" "xi")))]
   "TARGET_SSE2"
   "psrld\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_lshrv2di3"
   [(set (match_operand:V2DI 0 "register_operand" "=x")
                       (match_operand:TI 2 "nonmemory_operand" "xi")))]
   "TARGET_SSE2"
   "psrlq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 (define_insn "ashlv8hi3"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
                     (match_operand:TI 2 "nonmemory_operand" "xi")))]
   "TARGET_SSE2"
   "psllw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 (define_insn "ashlv4si3"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
                     (match_operand:TI 2 "nonmemory_operand" "xi")))]
   "TARGET_SSE2"
   "pslld\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_ashlv2di3"
   [(set (match_operand:V2DI 0 "register_operand" "=x")
                     (match_operand:TI 2 "nonmemory_operand" "xi")))]
   "TARGET_SSE2"
   "psllq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
 ;; we wouldn't need here it since we never generate TImode arithmetic.
                               (const_int 8)))] 30))]
   "TARGET_SSE2"
   "pslldq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_lshrti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
                                (const_int 8)))] 30))]
   "TARGET_SSE2"
   "pslrdq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sseishft")
+   (set_attr "mode" "TI")])
 
 ;; SSE unpack
 
                          (parallel [(const_int 0)]))))]
   "TARGET_SSE2"
   "unpckhpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_unpcklpd"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
                          (parallel [(const_int 1)]))))]
   "TARGET_SSE2"
   "unpcklpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 ;; MMX pack/unpack insns.
 
         (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
   "TARGET_SSE2"
   "packsswb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_packssdw"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
         (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
   "TARGET_SSE2"
   "packssdw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_packuswb"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
         (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
   "TARGET_SSE2"
   "packuswb\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_punpckhbw"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
         (const_int 21845)))]
   "TARGET_SSE2"
   "punpckhbw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_punpckhwd"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
         (const_int 85)))]
   "TARGET_SSE2"
   "punpckhwd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_punpckhdq"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
         (const_int 5)))]
   "TARGET_SSE2"
   "punpckhdq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_punpcklbw"
   [(set (match_operand:V16QI 0 "register_operand" "=x")
         (const_int 21845)))]
   "TARGET_SSE2"
   "punpcklbw\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_punpcklwd"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
         (const_int 85)))]
   "TARGET_SSE2"
   "punpcklwd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_punpckldq"
   [(set (match_operand:V4SI 0 "register_operand" "=x")
         (const_int 5)))]
   "TARGET_SSE2"
   "punpckldq\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 ;; SSE2 moves
 
   "@
    movapd\t{%1, %0|%0, %1}
    movapd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_movupd"
   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
   "@
    movupd\t{%1, %0|%0, %1}
    movupd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_movdqa"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
   "@
    movdqa\t{%1, %0|%0, %1}
    movdqa\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssemov")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_movdqu"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
   "@
    movdqu\t{%1, %0|%0, %1}
    movdqu\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_movdq2q"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=y")
                       (parallel [(const_int 0)])))]
   "TARGET_SSE2"
   "movdq2q\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_movq2dq"
   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x")
                         (const_vector:DI [(const_int 0)])))]
   "TARGET_SSE2"
   "movq2dq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_movhpd"
   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
         (const_int 2)))]
   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
   "movhpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_movlpd"
   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
         (const_int 1)))]
   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
   "movlpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_loadsd"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE2"
   "movsd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "DF")])
 
 (define_insn "sse2_movsd"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
         (const_int 1)))]
   "TARGET_SSE2"
   "movsd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "DF")])
 
 (define_insn "sse2_storesd"
   [(set (match_operand:DF 0 "memory_operand" "=m")
         (parallel [(const_int 0)])))]
   "TARGET_SSE2"
   "movsd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "DF")])
 
 (define_insn "sse2_shufpd"
   [(set (match_operand:V2DF 0 "register_operand" "=x")
   "TARGET_SSE2"
   ;; @@@ check operand order for intel/nonintel syntax
   "shufpd\t{%3, %2, %0|%0, %2, %3}"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "ssecvt")
+   (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_clflush"
   [(unspec_volatile [(match_operand:SI 0 "address_operand" "p")] 57)]
   "TARGET_SSE2"
   "clflush %0"
-  [(set_attr "type" "sse")])
+  [(set_attr "type" "sse")
+   (set_attr "memory" "unknown")])
 
 (define_expand "sse2_mfence"
   [(set (match_dup 0)