 -      if (GET_MODE (index) != Pmode)
 +      /* Allow 32bit addr in 64bit mode - usually makes no sense except in LEA */
 +      if (GET_MODE (index) != SImode && (!TARGET_64BIT || GET_MODE (index) != DImode))
- 	{
--	  reason = "index is not in Pmode";
++	{
 +	  reason = "index is not in proper mode";
 +	  goto report_error;
 +	}
 +
 +      if (base && GET_MODE (base) != GET_MODE (index))
-+	{
+ 	{
+-	  reason = "index is not in Pmode";
 +	  reason = "index and base have different modes";
  	  goto report_error;
  	}
  
-@@ -9529,7 +9678,7 @@
-     new_rtx = addr;
-   else if (TARGET_64BIT
- 	   && ix86_cmodel != CM_SMALL_PIC
--	   && gotoff_operand (addr, Pmode))
-+	   && gotoff_operand (addr, ptr_mode))
+@@ -9514,7 +9663,9 @@
+   rtx addr = orig;
+   rtx new_rtx = orig;
+   rtx base;
++  enum machine_mode orig_mode;
+ 
++  orig_mode = GET_MODE(orig);
+ #if TARGET_MACHO
+   if (TARGET_MACHO && !TARGET_64BIT)
      {
-       rtx tmpreg;
+@@ -9562,7 +9713,7 @@
+ 	}
+       else new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
+     }
+-  else if (!TARGET_64BIT && gotoff_operand (addr, Pmode))
++  else if (!TARGET_64BIT && gotoff_operand (addr, orig_mode))
+     {
        /* This symbol may be referenced via a displacement from the PIC
-@@ -9541,28 +9690,28 @@
+ 	 base address (@GOTOFF).  */
+@@ -9573,14 +9724,14 @@
  	addr = XEXP (addr, 0);
        if (GET_CODE (addr) == PLUS)
  	  {
 -            new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
-+            new_rtx = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, XEXP (addr, 0)),
++            new_rtx = gen_rtx_UNSPEC (orig_mode, gen_rtvec (1, XEXP (addr, 0)),
  				      UNSPEC_GOTOFF);
 -	    new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
-+	    new_rtx = gen_rtx_PLUS (ptr_mode, new_rtx, XEXP (addr, 1));
- 	  }
- 	else
--          new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
--      new_rtx = gen_rtx_CONST (Pmode, new_rtx);
-+          new_rtx = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
-+      new_rtx = gen_rtx_CONST (ptr_mode, new_rtx);
-       if (!reg)
--        tmpreg = gen_reg_rtx (Pmode);
-+        tmpreg = gen_reg_rtx (ptr_mode);
-       else
- 	tmpreg = reg;
-       emit_move_insn (tmpreg, new_rtx);
- 
-       if (reg != 0)
- 	{
--	  new_rtx = expand_simple_binop (Pmode, PLUS, reg, pic_offset_table_rtx,
-+	  new_rtx = expand_simple_binop (ptr_mode, PLUS, reg, pic_offset_table_rtx,
- 					 tmpreg, 1, OPTAB_DIRECT);
- 	  new_rtx = reg;
- 	}
--      else new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
-+      else new_rtx = gen_rtx_PLUS (ptr_mode, pic_offset_table_rtx, tmpreg);
-     }
--  else if (!TARGET_64BIT && gotoff_operand (addr, Pmode))
-+  else if (!TARGET_64BIT && gotoff_operand (addr, ptr_mode))
-     {
-       /* This symbol may be referenced via a displacement from the PIC
- 	 base address (@GOTOFF).  */
-@@ -9573,14 +9722,14 @@
- 	addr = XEXP (addr, 0);
-       if (GET_CODE (addr) == PLUS)
- 	  {
--            new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
-+            new_rtx = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, XEXP (addr, 0)),
- 				      UNSPEC_GOTOFF);
--	    new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
-+	    new_rtx = gen_rtx_PLUS (ptr_mode, new_rtx, XEXP (addr, 1));
++	    new_rtx = gen_rtx_PLUS (orig_mode, new_rtx, XEXP (addr, 1));
  	  }
  	else
 -          new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
 -      new_rtx = gen_rtx_CONST (Pmode, new_rtx);
 -      new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
-+          new_rtx = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
-+      new_rtx = gen_rtx_CONST (ptr_mode, new_rtx);
-+      new_rtx = gen_rtx_PLUS (ptr_mode, pic_offset_table_rtx, new_rtx);
++          new_rtx = gen_rtx_UNSPEC (orig_mode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
++      new_rtx = gen_rtx_CONST (orig_mode, new_rtx);
++      new_rtx = gen_rtx_PLUS (orig_mode, pic_offset_table_rtx, new_rtx);
  
        if (reg != 0)
  	{
-@@ -9602,19 +9751,19 @@
+@@ -9602,19 +9753,19 @@
                && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
              {
                rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), true);
 -              return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
-+              return gen_rtx_PLUS (ptr_mode, t, XEXP (XEXP (addr, 0), 1));
++              return gen_rtx_PLUS (orig_mode, t, XEXP (XEXP (addr, 0), 1));
              }
          }
  

     {
       rtx set = PATTERN (insn);
 
@@ -19057,7 +19252,10 @@
 
       gcc_assert (GET_CODE (set) == SET);
 

-	  new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTPCREL);
-	  new_rtx = gen_rtx_CONST (Pmode, new_rtx);
-	  new_rtx = gen_const_mem (Pmode, new_rtx);
+	  new_rtx = gen_rtx_UNSPEC (orig_mode, gen_rtvec (1, addr), UNSPEC_GOTPCREL);
+	  new_rtx = gen_rtx_CONST (orig_mode, new_rtx);
+	  new_rtx = gen_const_mem (orig_mode, new_rtx);
 	  set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
 
 	  if (reg == 0)
-	    reg = gen_reg_rtx (Pmode);
+	    reg = gen_reg_rtx (orig_mode);
 	  /* Use directly gen_movsi, otherwise the address is loaded
 	     into register for CSE.  We don't want to CSE this addresses,
 	     instead we CSE addresses from the GOT table, so skip this.  */
@@ -9628,16 +9779,16 @@
 
 	  if (reload_in_progress)
 	    df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
-	  new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
-	  new_rtx = gen_rtx_CONST (Pmode, new_rtx);
+	  new_rtx = gen_rtx_UNSPEC (orig_mode, gen_rtvec (1, addr), UNSPEC_GOT);
+	  new_rtx = gen_rtx_CONST (orig_mode, new_rtx);
 	  if (TARGET_64BIT)
-	    new_rtx = force_reg (Pmode, new_rtx);
-	  new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
-	  new_rtx = gen_const_mem (Pmode, new_rtx);
+	    new_rtx = force_reg (orig_mode, new_rtx);
+	  new_rtx = gen_rtx_PLUS (orig_mode, pic_offset_table_rtx, new_rtx);
+	  new_rtx = gen_const_mem (orig_mode, new_rtx);
 	  set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
 
 	  if (reg == 0)
-	    reg = gen_reg_rtx (Pmode);
+	    reg = gen_reg_rtx (orig_mode);
 	  emit_move_insn (reg, new_rtx);
 	  new_rtx = reg;
 	}
@@ -9653,7 +9804,7 @@
 	      new_rtx = reg;
 	    }
 	  else
-	    new_rtx = force_reg (Pmode, addr);
+	    new_rtx = force_reg (orig_mode, addr);
 	}
       else if (GET_CODE (addr) == CONST)
 	{
@@ -9674,18 +9825,18 @@
 
 	  /* Check first to see if this is a constant offset from a @GOTOFF
 	     symbol reference.  */
-	  if (gotoff_operand (op0, Pmode)
+	  if (gotoff_operand (op0, orig_mode)
 	      && CONST_INT_P (op1))
 	    {
 	      if (!TARGET_64BIT)
