OSDN Git Service

* config/i386/i386.md (SSEINT16): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Dec 2004 08:07:19 +0000 (08:07 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Dec 2004 08:07:19 +0000 (08:07 +0000)
        (movv16qi, movv8hi, movv4si, movv2di): Compress via macros.
        (movv16qi_internal, movv8hi_internal, movv4si_internal,
        movv2di_internal): Compress via macros.  Add SSE zero alternative.
        Fix pure SSE alternatives to use 'x' instead of 'Y'.
        (MMXINT8): New.
        (movv8qi, movv4hi, movv2si, movv8qi_internal, movv4hi_internal,
        movv2si_internal): Compress via macros.
        (SSEPUSH, MMXPUSH): New.
        (pushv18qi, pushv8hi, pushv4si, pushv2di, pushti, pushv4sf, pushv2df,
        pushv8qi, pushv4hi, pushv2si, pushv2sf): Compress via macros.

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

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

index 60b90b0..46a6063 100644 (file)
@@ -1,5 +1,19 @@
 2004-12-18  Richard Henderson  <rth@redhat.com>
 
+       * config/i386/i386.md (SSEINT16): New.
+       (movv16qi, movv8hi, movv4si, movv2di): Compress via macros.
+       (movv16qi_internal, movv8hi_internal, movv4si_internal,
+       movv2di_internal): Compress via macros.  Add SSE zero alternative.
+       Fix pure SSE alternatives to use 'x' instead of 'Y'.
+       (MMXINT8): New.
+       (movv8qi, movv4hi, movv2si, movv8qi_internal, movv4hi_internal,
+       movv2si_internal): Compress via macros.
+       (SSEPUSH, MMXPUSH): New.
+       (pushv18qi, pushv8hi, pushv4si, pushv2di, pushti, pushv4sf, pushv2df,
+       pushv8qi, pushv4hi, pushv2si, pushv2sf): Compress via macros.
+
+2004-12-18  Richard Henderson  <rth@redhat.com>
+
        PR middle-end/16417
        * c-decl.c (store_parm_decls): Clarify get_pending_sizes insertion
        comment.
index f270f74..b575d42 100644 (file)
 
 ;; Moves for SSE/MMX regs.
 
+(define_expand "movv4sf"
+  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+       (match_operand:V4SF 1 "nonimmediate_operand" ""))]
+  "TARGET_SSE"
+{
+  ix86_expand_vector_move (V4SFmode, operands);
+  DONE;
+})
+
 (define_insn "*movv4sf_internal"
   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
        (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
   operands[2] = CONST0_RTX (V4SFmode);
 })
 
-(define_insn "*movv4si_internal"
-  [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
-       (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
+(define_expand "movv2df"
+  [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
+       (match_operand:V2DF 1 "nonimmediate_operand" ""))]
   "TARGET_SSE"
 {
+  ix86_expand_vector_move (V2DFmode, operands);
+  DONE;
+})
+
+(define_insn "*movv2df_internal"
+  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
+       (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
+  "TARGET_SSE
+   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+{
   switch (which_alternative)
     {
     case 0:
       if (get_attr_mode (insn) == MODE_V4SF)
        return "xorps\t%0, %0";
       else
-       return "pxor\t%0, %0";
+       return "xorpd\t%0, %0";
     case 1:
     case 2:
       if (get_attr_mode (insn) == MODE_V4SF)
        return "movaps\t{%1, %0|%0, %1}";
       else
-       return "movdqa\t{%1, %0|%0, %1}";
+       return "movapd\t{%1, %0|%0, %1}";
     default:
       abort ();
     }
 }
   [(set_attr "type" "ssemov")
    (set (attr "mode")
-        (cond [(eq_attr "alternative" "0,1")
+        (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
+                (const_string "V4SF")
+              (eq_attr "alternative" "0,1")
                 (if_then_else
                   (ne (symbol_ref "optimize_size")
                       (const_int 0))
                   (const_string "V4SF")
-                  (const_string "TI"))
+                  (const_string "V2DF"))
               (eq_attr "alternative" "2")
                 (if_then_else
                   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
                        (ne (symbol_ref "optimize_size")
                            (const_int 0)))
                   (const_string "V4SF")
-                  (const_string "TI"))]
-              (const_string "TI")))])
+                  (const_string "V2DF"))]
+              (const_string "V2DF")))])
 
-(define_insn "*movv2di_internal"
-  [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
-       (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
+(define_split
+  [(set (match_operand:V2DF 0 "register_operand" "")
+       (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
+  "TARGET_SSE2 && reload_completed"
+  [(set (match_dup 0)
+       (vec_merge:V2DF
+        (vec_duplicate:V2DF (match_dup 1))
+        (match_dup 2)
+        (const_int 1)))]
+{
+  operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
+  operands[2] = CONST0_RTX (V2DFmode);
+})
+
+;; 16 byte integral modes handled by SSE, minus TImode, which gets
+;; special-cased for TARGET_64BIT.
+(define_mode_macro SSEINT16 [V16QI V8HI V4SI V2DI])
+
+(define_expand "mov<mode>"
+  [(set (match_operand:SSEINT16 0 "nonimmediate_operand" "")
+       (match_operand:SSEINT16 1 "nonimmediate_operand" ""))]
   "TARGET_SSE"
 {
+  ix86_expand_vector_move (<MODE>mode, operands);
+  DONE;
+})
+
+(define_insn "*mov<mode>_internal"
+  [(set (match_operand:SSEINT16 0 "nonimmediate_operand" "=x,x ,m")
+       (match_operand:SSEINT16 1 "vector_move_operand"  "C ,xm,x"))]
+  "TARGET_SSE
+   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+{
   switch (which_alternative)
     {
     case 0:
                   (const_string "TI"))]
               (const_string "TI")))])
 
-(define_split
-  [(set (match_operand:V2DF 0 "register_operand" "")
-       (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
-  "TARGET_SSE2 && reload_completed"
-  [(set (match_dup 0)
-       (vec_merge:V2DF
-        (vec_duplicate:V2DF (match_dup 1))
-        (match_dup 2)
-        (const_int 1)))]
+;; 8 byte integral modes handled by MMX (and by extension, SSE)
+(define_mode_macro MMXINT8 [V8QI V4HI V2SI])
+
+(define_expand "mov<mode>"
+  [(set (match_operand:MMXINT8 0 "nonimmediate_operand" "")
+       (match_operand:MMXINT8 1 "nonimmediate_operand" ""))]
+  "TARGET_MMX"
 {
-  operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
-  operands[2] = CONST0_RTX (V2DFmode);
+  ix86_expand_vector_move (<MODE>mode, operands);
+  DONE;
 })
 
-(define_insn "*movv8qi_internal"
-  [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
-       (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
+(define_insn "*mov<mode>_internal"
+  [(set (match_operand:MMXINT8 0 "nonimmediate_operand"
+                                       "=y,y ,m,!y,!*Y,*x,?*x,?m")
+       (match_operand:MMXINT8 1 "vector_move_operand"
+                                       "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
   "TARGET_MMX
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
     movq\t{%1, %0|%0, %1}
     movdq2q\t{%1, %0|%0, %1}
     movq2dq\t{%1, %0|%0, %1}
-    movq\t{%1, %0|%0, %1}
-    movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
-   (set_attr "mode" "DI")])
-
-(define_insn "*movv4hi_internal"
-  [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
-       (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
-  "TARGET_MMX
-   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
-  "@
     pxor\t%0, %0
     movq\t{%1, %0|%0, %1}
-    movq\t{%1, %0|%0, %1}
-    movdq2q\t{%1, %0|%0, %1}
-    movq2dq\t{%1, %0|%0, %1}
-    movq\t{%1, %0|%0, %1}
     movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
+  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
    (set_attr "mode" "DI")])
 
-(define_insn "*movv2si_internal"
-  [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
-       (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
-  "TARGET_MMX
-   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
-  "@
-    pxor\t%0, %0
-    movq\t{%1, %0|%0, %1}
-    movq\t{%1, %0|%0, %1}
-    movdq2q\t{%1, %0|%0, %1}
-    movq2dq\t{%1, %0|%0, %1}
-    movq\t{%1, %0|%0, %1}
-    movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
-   (set_attr "mode" "DI")])
+(define_expand "movv2sf"
+  [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
+       (match_operand:V2SF 1 "nonimmediate_operand" ""))]
+  "TARGET_MMX"
+{
+  ix86_expand_vector_move (V2SFmode, operands);
+  DONE;
+})
 
 (define_insn "*movv2sf_internal"
-  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
-        (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
+  [(set (match_operand:V2SF 0 "nonimmediate_operand"
+                                       "=y,y ,m,!y,!*Y,*x,?*x,?m")
+        (match_operand:V2SF 1 "vector_move_operand"
+                                       "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
   "TARGET_MMX
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
     movq\t{%1, %0|%0, %1}
     movdq2q\t{%1, %0|%0, %1}
     movq2dq\t{%1, %0|%0, %1}
+    xorps\t%0, %0
     movlps\t{%1, %0|%0, %1}
     movlps\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
-   (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
+  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
+   (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
 
 (define_expand "movti"
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
   DONE;
 })
 
-(define_expand "movtf"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "")
-       (match_operand:TF 1 "nonimmediate_operand" ""))]
-  "TARGET_64BIT"
-{
-  ix86_expand_move (TFmode, operands);
-  DONE;
-})
-
-(define_insn "*movv2df_internal"
-  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
-       (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
-  "TARGET_SSE
-   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
-{
-  switch (which_alternative)
-    {
-    case 0:
-      if (get_attr_mode (insn) == MODE_V4SF)
-       return "xorps\t%0, %0";
-      else
-       return "xorpd\t%0, %0";
-    case 1:
-    case 2:
-      if (get_attr_mode (insn) == MODE_V4SF)
-       return "movaps\t{%1, %0|%0, %1}";
-      else
-       return "movapd\t{%1, %0|%0, %1}";
-    default:
-      abort ();
-    }
-}
-  [(set_attr "type" "ssemov")
-   (set (attr "mode")
-        (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
-                (const_string "V4SF")
-              (eq_attr "alternative" "0,1")
-                (if_then_else
-                  (ne (symbol_ref "optimize_size")
-                      (const_int 0))
-                  (const_string "V4SF")
-                  (const_string "V2DF"))
-              (eq_attr "alternative" "2")
-                (if_then_else
-                  (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
-                           (const_int 0))
-                       (ne (symbol_ref "optimize_size")
-                           (const_int 0)))
-                  (const_string "V4SF")
-                  (const_string "V2DF"))]
-              (const_string "V2DF")))])
-
-(define_insn "*movv8hi_internal"
-  [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
-       (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
-  "TARGET_SSE
-   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
-{
-  switch (which_alternative)
-    {
-    case 0:
-      if (get_attr_mode (insn) == MODE_V4SF)
-       return "xorps\t%0, %0";
-      else
-       return "pxor\t%0, %0";
-    case 1:
-    case 2:
-      if (get_attr_mode (insn) == MODE_V4SF)
-       return "movaps\t{%1, %0|%0, %1}";
-      else
-       return "movdqa\t{%1, %0|%0, %1}";
-    default:
-      abort ();
-    }
-}
-  [(set_attr "type" "ssemov")
-   (set (attr "mode")
-        (cond [(eq_attr "alternative" "0,1")
-                (if_then_else
-                  (ne (symbol_ref "optimize_size")
-                      (const_int 0))
-                  (const_string "V4SF")
-                  (const_string "TI"))
-              (eq_attr "alternative" "2")
-                (if_then_else
-                  (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
-                           (const_int 0))
-                       (ne (symbol_ref "optimize_size")
-                           (const_int 0)))
-                  (const_string "V4SF")
-                  (const_string "TI"))]
-              (const_string "TI")))])
-
-(define_insn "*movv16qi_internal"
-  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
-       (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
-  "TARGET_SSE
-   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
-{
-  switch (which_alternative)
-    {
-    case 0:
-      if (get_attr_mode (insn) == MODE_V4SF)
-       return "xorps\t%0, %0";
-      else
-       return "pxor\t%0, %0";
-    case 1:
-    case 2:
-      if (get_attr_mode (insn) == MODE_V4SF)
-       return "movaps\t{%1, %0|%0, %1}";
-      else
-       return "movdqa\t{%1, %0|%0, %1}";
-    default:
-      abort ();
-    }
-}
-  [(set_attr "type" "ssemov")
-   (set (attr "mode")
-        (cond [(eq_attr "alternative" "0,1")
-                (if_then_else
-                  (ne (symbol_ref "optimize_size")
-                      (const_int 0))
-                  (const_string "V4SF")
-                  (const_string "TI"))
-              (eq_attr "alternative" "2")
-                (if_then_else
-                  (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
-                           (const_int 0))
-                       (ne (symbol_ref "optimize_size")
-                           (const_int 0)))
-                  (const_string "V4SF")
-                  (const_string "TI"))]
-              (const_string "TI")))])
-
-(define_expand "movv2df"
-  [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
-       (match_operand:V2DF 1 "nonimmediate_operand" ""))]
-  "TARGET_SSE"
-{
-  ix86_expand_vector_move (V2DFmode, operands);
-  DONE;
-})
-
-(define_expand "movv8hi"
-  [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
-       (match_operand:V8HI 1 "nonimmediate_operand" ""))]
-  "TARGET_SSE"
-{
-  ix86_expand_vector_move (V8HImode, operands);
-  DONE;
-})
-
-(define_expand "movv16qi"
-  [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
-       (match_operand:V16QI 1 "nonimmediate_operand" ""))]
-  "TARGET_SSE"
-{
-  ix86_expand_vector_move (V16QImode, operands);
-  DONE;
-})
-
-(define_expand "movv4sf"
-  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
-       (match_operand:V4SF 1 "nonimmediate_operand" ""))]
-  "TARGET_SSE"
-{
-  ix86_expand_vector_move (V4SFmode, operands);
-  DONE;
-})
-
-(define_expand "movv4si"
-  [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
-       (match_operand:V4SI 1 "nonimmediate_operand" ""))]
-  "TARGET_SSE"
-{
-  ix86_expand_vector_move (V4SImode, operands);
-  DONE;
-})
-
-(define_expand "movv2di"
-  [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
-       (match_operand:V2DI 1 "nonimmediate_operand" ""))]
-  "TARGET_SSE"
-{
-  ix86_expand_vector_move (V2DImode, operands);
-  DONE;
-})
-
-(define_expand "movv2si"
-  [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
-       (match_operand:V2SI 1 "nonimmediate_operand" ""))]
-  "TARGET_MMX"
-{
-  ix86_expand_vector_move (V2SImode, operands);
-  DONE;
-})
-
-(define_expand "movv4hi"
-  [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
-       (match_operand:V4HI 1 "nonimmediate_operand" ""))]
-  "TARGET_MMX"
-{
-  ix86_expand_vector_move (V4HImode, operands);
-  DONE;
-})
-
-(define_expand "movv8qi"
-  [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
-       (match_operand:V8QI 1 "nonimmediate_operand" ""))]
-  "TARGET_MMX"
-{
-  ix86_expand_vector_move (V8QImode, operands);
-  DONE;
-})
-
-(define_expand "movv2sf"
-  [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
-       (match_operand:V2SF 1 "nonimmediate_operand" ""))]
-  "TARGET_MMX"
-{
-  ix86_expand_vector_move (V2SFmode, operands);
-  DONE;
-})
-
-(define_insn "*pushti"
-  [(set (match_operand:TI 0 "push_operand" "=<")
-       (match_operand:TI 1 "register_operand" "x"))]
-  "TARGET_SSE"
-  "#")
-
-(define_insn "*pushv2df"
-  [(set (match_operand:V2DF 0 "push_operand" "=<")
-       (match_operand:V2DF 1 "register_operand" "x"))]
-  "TARGET_SSE"
-  "#")
-
-(define_insn "*pushv2di"
-  [(set (match_operand:V2DI 0 "push_operand" "=<")
-       (match_operand:V2DI 1 "register_operand" "x"))]
-  "TARGET_SSE"
-  "#")
-
-(define_insn "*pushv8hi"
-  [(set (match_operand:V8HI 0 "push_operand" "=<")
-       (match_operand:V8HI 1 "register_operand" "x"))]
-  "TARGET_SSE"
-  "#")
-
-(define_insn "*pushv16qi"
-  [(set (match_operand:V16QI 0 "push_operand" "=<")
-       (match_operand:V16QI 1 "register_operand" "x"))]
-  "TARGET_SSE"
-  "#")
-
-(define_insn "*pushv4sf"
-  [(set (match_operand:V4SF 0 "push_operand" "=<")
-       (match_operand:V4SF 1 "register_operand" "x"))]
-  "TARGET_SSE"
-  "#")
-
-(define_insn "*pushv4si"
-  [(set (match_operand:V4SI 0 "push_operand" "=<")
-       (match_operand:V4SI 1 "register_operand" "x"))]
-  "TARGET_SSE"
-  "#")
-
-(define_insn "*pushv2si"
-  [(set (match_operand:V2SI 0 "push_operand" "=<")
-       (match_operand:V2SI 1 "register_operand" "y"))]
-  "TARGET_MMX"
-  "#")
-
-(define_insn "*pushv4hi"
-  [(set (match_operand:V4HI 0 "push_operand" "=<")
-       (match_operand:V4HI 1 "register_operand" "y"))]
-  "TARGET_MMX"
-  "#")
-
-(define_insn "*pushv8qi"
-  [(set (match_operand:V8QI 0 "push_operand" "=<")
-       (match_operand:V8QI 1 "register_operand" "y"))]
-  "TARGET_MMX"
-  "#")
-
-(define_insn "*pushv2sf"
-  [(set (match_operand:V2SF 0 "push_operand" "=<")
-       (match_operand:V2SF 1 "register_operand" "y"))]
-  "TARGET_MMX"
-  "#")
-
-(define_split
-  [(set (match_operand 0 "push_operand" "")
-       (match_operand 1 "register_operand" ""))]
-  "!TARGET_64BIT && reload_completed
-   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
-  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
-   (set (match_dup 2) (match_dup 1))]
-  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
-                                stack_pointer_rtx);
-   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
-
-(define_split
-  [(set (match_operand 0 "push_operand" "")
-       (match_operand 1 "register_operand" ""))]
-  "TARGET_64BIT && reload_completed
-   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
-  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
-   (set (match_dup 2) (match_dup 1))]
-  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
-                                stack_pointer_rtx);
-   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
-
-
 (define_insn "*movti_internal"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
        (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
                   (const_string "TI"))]
               (const_string "DI")))])
 
-(define_insn "*movtf_rex64"
+(define_expand "movtf"
+  [(set (match_operand:TF 0 "nonimmediate_operand" "")
+       (match_operand:TF 1 "nonimmediate_operand" ""))]
+  "TARGET_64BIT"
+{
+  ix86_expand_move (TFmode, operands);
+  DONE;
+})
+
+(define_insn "*movtf_internal"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
        (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
   "TARGET_64BIT
                   (const_string "TI"))]
               (const_string "DI")))])
 
+(define_mode_macro SSEPUSH [V16QI V8HI V4SI V2DI TI V4SF V2DF])
+
+(define_insn "*push<mode>"
+  [(set (match_operand:SSEPUSH 0 "push_operand" "=<")
+       (match_operand:SSEPUSH 1 "register_operand" "x"))]
+  "TARGET_SSE"
+  "#")
+
+(define_mode_macro MMXPUSH [V8QI V4HI V2SI V2SF])
+
+(define_insn "*push<mode>"
+  [(set (match_operand:MMXPUSH 0 "push_operand" "=<")
+       (match_operand:MMXPUSH 1 "register_operand" "xy"))]
+  "TARGET_MMX"
+  "#")
+
+(define_split
+  [(set (match_operand 0 "push_operand" "")
+       (match_operand 1 "register_operand" ""))]
+  "!TARGET_64BIT && reload_completed
+   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
+  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
+   (set (match_dup 2) (match_dup 1))]
+  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
+                                stack_pointer_rtx);
+   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
+
+(define_split
+  [(set (match_operand 0 "push_operand" "")
+       (match_operand 1 "register_operand" ""))]
+  "TARGET_64BIT && reload_completed
+   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
+  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
+   (set (match_dup 2) (match_dup 1))]
+  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
+                                stack_pointer_rtx);
+   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
+
+
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
         (match_operand:TI 1 "general_operand" ""))]