Index: predicates.md
===================================================================
--- predicates.md	(revision 176462)
+++ predicates.md	(working copy)
@@ -796,7 +796,7 @@
 
 ;; Return true if op if a valid address, and does not contain
 ;; a segment override.
-(define_special_predicate "no_seg_address_operand"
+(define_predicate "no_seg_address_operand"
   (match_operand 0 "address_operand")
 {
   struct ix86_address parts;
Index: i386.c
===================================================================
--- i386.c	(revision 176462)
+++ i386.c	(working copy)
@@ -11085,8 +11085,16 @@ ix86_decompose_address (rtx addr, struct
   int retval = 1;
   enum ix86_address_seg seg = SEG_DEFAULT;
 
-  if (REG_P (addr) || GET_CODE (addr) == SUBREG)
+  if (REG_P (addr))
     base = addr;
+  else if (GET_CODE (addr) == SUBREG)
+    {
+      /* Allow only subregs of DImode hard regs.  */
+      if (register_no_elim_operand (SUBREG_REG (addr), DImode))
+	base = addr;
+      else
+	return 0;
+    }
   else if (GET_CODE (addr) == PLUS)
     {
       rtx addends[4], op;
@@ -11643,8 +11651,7 @@ ix86_legitimate_address_p (enum machine_
 	/* Base is not a register.  */
 	return false;
 
-      if (GET_MODE (base) != Pmode)
-	/* Base is not in Pmode.  */
+      if (GET_MODE (base) != SImode && GET_MODE (base) != DImode)
 	return false;
 
       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
@@ -11672,8 +11679,7 @@ ix86_legitimate_address_p (enum machine_
 	/* Index is not a register.  */
 	return false;
 
-      if (GET_MODE (index) != Pmode)
-	/* Index is not in Pmode.  */
+      if (GET_MODE (index) != SImode && GET_MODE (index) != DImode)
 	return false;
 
       if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
