Index: i386/i386.md
===================================================================
--- i386/i386.md	(revision 177430)
+++ i386/i386.md	(working copy)
@@ -1648,9 +1648,11 @@
 
 (define_insn "*push<mode>2"
   [(set (match_operand:DWI 0 "push_operand" "=<")
-	(match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
+	(match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
   ""
-  "#")
+  "#"
+  [(set_attr "type" "multi")
+   (set_attr "mode" "<MODE>")])
 
 (define_split
   [(set (match_operand:TI 0 "push_operand" "")
@@ -2704,7 +2706,7 @@
 ;; only once, but this ought to be handled elsewhere).
 
 (define_insn "*pushxf_nointeger"
-  [(set (match_operand:XF 0 "push_operand" "=X,X")
+  [(set (match_operand:XF 0 "push_operand" "=<,<")
 	(match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
   "optimize_function_for_size_p (cfun)"
 {
@@ -2724,6 +2726,18 @@
    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
 
+(define_insn "*pushdf_rex64"
+  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
+	(match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,Y2"))]
+  "TARGET_64BIT"
+{
+  /* This insn should be already split before reg-stack.  */
+  gcc_unreachable ();
+}
+  [(set_attr "type" "multi")
+   (set_attr "unit" "i387,*,*")
+   (set_attr "mode" "DF,DI,DF")])
+
 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
 ;; Size of pushdf using integer instructions is 2+2*memory operand size
 ;; On the average, pushdf using integers can be still shorter.
@@ -2731,14 +2745,14 @@
 (define_insn "*pushdf"
   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
 	(match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
-  ""
+  "!TARGET_64BIT"
 {
   /* This insn should be already split before reg-stack.  */
   gcc_unreachable ();
 }
   [(set_attr "type" "multi")
    (set_attr "unit" "i387,*,*")
-   (set_attr "mode" "DF,SI,DF")])
+   (set_attr "mode" "DF,DI,DF")])
 
 ;; %%% Kill this when call knows how to work this out.
 (define_split
@@ -5431,7 +5445,7 @@
 
 (define_insn "*lea_1"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
-	(match_operand:SWI48 1 "no_seg_address_operand" "p"))]
+	(match_operand:SWI48 1 "lea_address_operand" "p"))]
   ""
   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
@@ -5440,7 +5454,7 @@
 (define_insn "*lea_1_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(zero_extend:DI
-	  (match_operand:SI 1 "no_seg_address_operand" "p")))]
+	  (match_operand:SI 1 "lea_address_operand" "p")))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %k0|%k0, %a1}"
   [(set_attr "type" "lea")
@@ -5448,7 +5462,7 @@
 
 (define_insn "*lea_2"
   [(set (match_operand:SI 0 "register_operand" "=r")
-	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
+	(subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
@@ -5457,7 +5471,7 @@
 (define_insn "*lea_2_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(zero_extend:DI
-	  (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
+	  (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %k0|%k0, %a1}"
   [(set_attr "type" "lea")
Index: i386/predicates.md
===================================================================
--- i386/predicates.md	(revision 177430)
+++ i386/predicates.md	(working copy)
@@ -793,9 +793,9 @@
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "const0_operand")))
 
-;; Return true if op if a valid address, and does not contain
+;; Return true if op if a valid address for LEA, and does not contain
 ;; a segment override.
-(define_predicate "no_seg_address_operand"
+(define_predicate "lea_address_operand"
   (match_operand 0 "address_operand")
 {
   struct ix86_address parts;
@@ -840,6 +840,11 @@
   ok = ix86_decompose_address (op, &parts);
   gcc_assert (ok);
 
+  if (parts.base && GET_CODE (parts.base) == SUBREG)
+    parts.base = SUBREG_REG (parts.base);
+  if (parts.index && GET_CODE (parts.index) == SUBREG)
+    parts.index = SUBREG_REG (parts.index);
+
   /* Look for some component that isn't known to be aligned.  */
   if (parts.index)
     {
@@ -903,6 +908,12 @@
 
   ok = ix86_decompose_address (XEXP (op, 0), &parts);
   gcc_assert (ok);
+
+  if (parts.base && GET_CODE (parts.base) == SUBREG)
+    parts.base = SUBREG_REG (parts.base);
+  if (parts.index && GET_CODE (parts.index) == SUBREG)
+    parts.index = SUBREG_REG (parts.index);
+
   if (parts.base == NULL_RTX
       || parts.base == arg_pointer_rtx
       || parts.base == frame_pointer_rtx
Index: i386/i386.c
===================================================================
--- i386/i386.c	(revision 177430)
+++ i386/i386.c	(working copy)
@@ -14098,6 +14098,20 @@ ix86_print_operand_address (FILE *file, rtx addr)
 
   gcc_assert (ok);
 
+  if (parts.base && GET_CODE (parts.base) == SUBREG)
+    {
+      rtx tmp = SUBREG_REG (parts.base);
+      parts.base = simplify_subreg (GET_MODE (parts.base),
+				    tmp, GET_MODE (tmp), 0);
+    }
+
+  if (parts.index && GET_CODE (parts.index) == SUBREG)
+    {
+      rtx tmp = SUBREG_REG (parts.index);
+      parts.index = simplify_subreg (GET_MODE (parts.index),
+				     tmp, GET_MODE (tmp), 0);
+    }
+
   base = parts.base;
   index = parts.index;
   disp = parts.disp;
