public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Ulrich Weigand" <uweigand@de.ibm.com>
To: dj@redhat.com
Cc: gcc-patches@gcc.gnu.org
Subject: [patch] Address-space-aware base registers (Re: m32c support for named addr spaces branch)
Date: Thu, 29 Oct 2009 18:37:00 -0000	[thread overview]
Message-ID: <200910291832.n9TIWENj028460@d12av02.megacenter.de.ibm.com> (raw)
In-Reply-To: <200910191436.n9JEaeP8020344@d12av02.megacenter.de.ibm.com> from "Ulrich Weigand" at Oct 19, 2009 04:36:40 PM

> DJ Delorie wrote:
> 
> > How do I tell gcc which registers are legal base registers for the
> > __far addressing mode?  It tries $a1 and $r0, but only $a0 is allowed.
> > 
> > It works just fine without the "__far", and in fact chooses $a0
> > although $a1 *would* work then.
> 
> As far as I can see, there's two things to consider:
> 
> - The legitimate_address target macro, when called in "strict" mode,
>   must refuse addresses that use invalid base registers for the
>   given address space.
> 
> - The base_reg_class and ok_for_base_p_1 routines in addresses.h should
>   take the target address space into account.
> 
> The first should be easily doable with the current address-space-aware
> variant of legitimate_address.
> 
> The second, however, seems to require additional changes:  the callers
> of the base_reg_class / ok_for_base_p_1 routines need to be adapted to
> pass the address space, and we need to define new target macros as
> variants of MODE_CODE_BASE_REG_CLASS / REGNO_MODE_CODE_OK_FOR_BASE_P
> that take an address space.

I've now implemented this idea with the following patch.  Could you
try whether this solves the problem for you?

Bye,
Ulrich


ChangeLog:

	* doc/tm.texi (MODE_CODE_BASE_REG_CLASS): Add address space
	argument.
	(REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise.

	* config/cris/cris.h (MODE_CODE_BASE_REG_CLASS): Add address
	space argument.
	(REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise.
	* config/bfin/bfin.h (MODE_CODE_BASE_REG_CLASS): Likewise.
	(REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise.

	* addresses.h (base_reg_class): Add address space argument.
	Pass to MODE_CODE_BASE_REG_CLASS.
	(ok_for_base_p_1): Add address space argument.  Pass to
	REGNO_MODE_CODE_OK_FOR_BASE_P.
	(regno_ok_for_base_p): Add address space argument.  Pass to
	ok_for_base_p_1.

	* regrename.c (scan_rtx_address): Add address space argument.
	Pass address space to regno_ok_for_base_p and base_reg_class.
	Update recursive calls.
	(scan_rtx): Pass address space to scan_rtx_address.
	(build_def_use): Likewise.
	* regcprop.c (replace_oldest_value_addr): Add address space
	argument.  Pass to regno_ok_for_base_p and base_reg_class.
	Update recursive calls.
	(replace_oldest_value_mem): Pass address space to
	replace_oldest_value_addr.
	(copyprop_hardreg_forward_1): Likewise.

	* reload.c (find_reloads_address_1): Add address space argument.
	Pass address space to base_reg_class and regno_ok_for_base_p.
	Update recursive calls.
	(find_reloads_address): Pass address space to base_reg_class,
	regno_ok_for_base_p, and find_reloads_address_1.
	(find_reloads): Pass address space to base_reg_class.
	(find_reloads_subreg_address): Likewise.

	* ira-costs.c (record_reg_classes): Update calls to base_reg_class.
	(ok_for_base_p_nonstrict): Add address space argument.  Pass to
	ok_for_base_p_1.
	(record_address_regs): Add address space argument.  Pass to
	base_reg_class and ok_for_base_p_nonstrict.  Update recursive calls.
	(record_operand_costs): Pass address space to record_address_regs.
	(scan_one_insn): Likewise.

	* caller-save.c (init_caller_save): Update call to base_reg_class.
	* ira-conflicts.c (ira_build_conflicts): Likewise.
	* reload1.c (maybe_fix_stack_asms): Likewise.


Index: gcc/regrename.c
===================================================================
*** gcc/regrename.c	(revision 153564)
--- gcc/regrename.c	(working copy)
*************** static void do_replace (struct du_chain 
*** 83,89 ****
  static void scan_rtx_reg (rtx, rtx *, enum reg_class,
  			  enum scan_actions, enum op_type, int);
  static void scan_rtx_address (rtx, rtx *, enum reg_class,
! 			      enum scan_actions, enum machine_mode);
  static void scan_rtx (rtx, rtx *, enum reg_class, enum scan_actions,
  		      enum op_type, int);
  static struct du_chain *build_def_use (basic_block);
--- 83,90 ----
  static void scan_rtx_reg (rtx, rtx *, enum reg_class,
  			  enum scan_actions, enum op_type, int);
  static void scan_rtx_address (rtx, rtx *, enum reg_class,
! 			      enum scan_actions, enum machine_mode,
! 			      addr_space_t);
  static void scan_rtx (rtx, rtx *, enum reg_class, enum scan_actions,
  		      enum op_type, int);
  static struct du_chain *build_def_use (basic_block);
*************** scan_rtx_reg (rtx insn, rtx *loc, enum r
*** 527,533 ****
  
  static void
  scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
! 		  enum scan_actions action, enum machine_mode mode)
  {
    rtx x = *loc;
    RTX_CODE code = GET_CODE (x);
--- 528,535 ----
  
  static void
  scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
! 		  enum scan_actions action, enum machine_mode mode,
! 		  addr_space_t as)
  {
    rtx x = *loc;
    RTX_CODE code = GET_CODE (x);
*************** scan_rtx_address (rtx insn, rtx *loc, en
*** 595,609 ****
  	    unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
  
  	    if (REGNO_OK_FOR_INDEX_P (regno1)
! 		&& regno_ok_for_base_p (regno0, mode, PLUS, REG))
  	      index_op = 1;
  	    else if (REGNO_OK_FOR_INDEX_P (regno0)
! 		     && regno_ok_for_base_p (regno1, mode, PLUS, REG))
  	      index_op = 0;
! 	    else if (regno_ok_for_base_p (regno0, mode, PLUS, REG)
  		     || REGNO_OK_FOR_INDEX_P (regno1))
  	      index_op = 1;
! 	    else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
  	      index_op = 0;
  	    else
  	      index_op = 1;
--- 597,611 ----
  	    unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
  
  	    if (REGNO_OK_FOR_INDEX_P (regno1)
! 		&& regno_ok_for_base_p (regno0, mode, as, PLUS, REG))
  	      index_op = 1;
  	    else if (REGNO_OK_FOR_INDEX_P (regno0)
! 		     && regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
  	      index_op = 0;
! 	    else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG)
  		     || REGNO_OK_FOR_INDEX_P (regno1))
  	      index_op = 1;
! 	    else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
  	      index_op = 0;
  	    else
  	      index_op = 1;
*************** scan_rtx_address (rtx insn, rtx *loc, en
*** 626,635 ****
  	  }
  
  	if (locI)
! 	  scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
  	if (locB)
! 	  scan_rtx_address (insn, locB, base_reg_class (mode, PLUS, index_code),
! 			    action, mode);
  
  	return;
        }
--- 628,638 ----
  	  }
  
  	if (locI)
! 	  scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode, as);
  	if (locB)
! 	  scan_rtx_address (insn, locB,
! 			    base_reg_class (mode, as, PLUS, index_code),
! 			    action, mode, as);
  
  	return;
        }
*************** scan_rtx_address (rtx insn, rtx *loc, en
*** 649,656 ****
  
      case MEM:
        scan_rtx_address (insn, &XEXP (x, 0),
! 			base_reg_class (GET_MODE (x), MEM, SCRATCH), action,
! 			GET_MODE (x));
        return;
  
      case REG:
--- 652,660 ----
  
      case MEM:
        scan_rtx_address (insn, &XEXP (x, 0),
! 			base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x),
! 					MEM, SCRATCH),
! 			action, GET_MODE (x), MEM_ADDR_SPACE (x));
        return;
  
      case REG:
*************** scan_rtx_address (rtx insn, rtx *loc, en
*** 665,674 ****
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	scan_rtx_address (insn, &XEXP (x, i), cl, action, mode);
        else if (fmt[i] == 'E')
  	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! 	  scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode);
      }
  }
  
--- 669,678 ----
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	scan_rtx_address (insn, &XEXP (x, i), cl, action, mode, as);
        else if (fmt[i] == 'E')
  	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! 	  scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode, as);
      }
  }
  
*************** scan_rtx (rtx insn, rtx *loc, enum reg_c
*** 701,708 ****
  
      case MEM:
        scan_rtx_address (insn, &XEXP (x, 0),
! 			base_reg_class (GET_MODE (x), MEM, SCRATCH), action,
! 			GET_MODE (x));
        return;
  
      case SET:
--- 705,713 ----
  
      case MEM:
        scan_rtx_address (insn, &XEXP (x, 0),
! 			base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x),
! 					MEM, SCRATCH),
! 			action, GET_MODE (x), MEM_ADDR_SPACE (x));
        return;
  
      case SET:
*************** build_def_use (basic_block bb)
*** 891,897 ****
  		continue;
  
  	      if (recog_op_alt[opn][alt].is_address)
! 		scan_rtx_address (insn, loc, cl, mark_read, VOIDmode);
  	      else
  		scan_rtx (insn, loc, cl, mark_read, type, 0);
  	    }
--- 896,903 ----
  		continue;
  
  	      if (recog_op_alt[opn][alt].is_address)
! 		scan_rtx_address (insn, loc, cl, mark_read,
! 				  VOIDmode, ADDR_SPACE_GENERIC);
  	      else
  		scan_rtx (insn, loc, cl, mark_read, type, 0);
  	    }
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi	(revision 153571)
--- gcc/doc/tm.texi	(working copy)
*************** register address.  You should define thi
*** 2495,2506 ****
  addresses have different requirements than other base register uses.
  @end defmac
  
! @defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{outer_code}, @var{index_code})
  A C expression whose value is the register class to which a valid
! base register must belong.  @var{outer_code} and @var{index_code} define the
! context in which the base register occurs.  @var{outer_code} is the code of
! the immediately enclosing expression (@code{MEM} for the top level of an
! address, @code{ADDRESS} for something that occurs in an
  @code{address_operand}).  @var{index_code} is the code of the corresponding
  index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} otherwise.
  @end defmac
--- 2495,2507 ----
  addresses have different requirements than other base register uses.
  @end defmac
  
! @defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{address_space}, @var{outer_code}, @var{index_code})
  A C expression whose value is the register class to which a valid
! base register for a memory reference in mode @var{mode} to address
! space @var{address_space} must belong.  @var{outer_code} and @var{index_code}
! define the context in which the base register occurs.  @var{outer_code} is
! the code of the immediately enclosing expression (@code{MEM} for the top level
! of an address, @code{ADDRESS} for something that occurs in an
  @code{address_operand}).  @var{index_code} is the code of the corresponding
  index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} otherwise.
  @end defmac
*************** Use of this macro is deprecated; please 
*** 2555,2562 ****
  This macro also has strict and non-strict variants.
  @end defmac
  
! @defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{outer_code}, @var{index_code})
! A C expression that is just like @code{REGNO_MODE_OK_FOR_BASE_P}, except
  that that expression may examine the context in which the register
  appears in the memory reference.  @var{outer_code} is the code of the
  immediately enclosing expression (@code{MEM} if at the top level of the
--- 2556,2566 ----
  This macro also has strict and non-strict variants.
  @end defmac
  
! @defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{address_space}, @var{outer_code}, @var{index_code})
! A C expression which is nonzero if register number @var{num} is
! suitable for use as a base register in operand addresses, accessing
! memory in mode @var{mode} in address space @var{address_space}.
! This is similar to @code{REGNO_MODE_OK_FOR_BASE_P}, except
  that that expression may examine the context in which the register
  appears in the memory reference.  @var{outer_code} is the code of the
  immediately enclosing expression (@code{MEM} if at the top level of the
Index: gcc/ira-conflicts.c
===================================================================
*** gcc/ira-conflicts.c	(revision 153564)
--- gcc/ira-conflicts.c	(working copy)
*************** ira_debug_conflicts (bool reg_p)
*** 761,766 ****
--- 761,767 ----
  void
  ira_build_conflicts (void)
  {
+   enum reg_class base;
    ira_allocno_t a;
    ira_allocno_iterator ai;
    HARD_REG_SET temp_hard_reg_set;
*************** ira_build_conflicts (void)
*** 787,798 ****
  	  ira_free (conflicts);
  	}
      }
!   if (! CLASS_LIKELY_SPILLED_P (base_reg_class (VOIDmode, ADDRESS, SCRATCH)))
      CLEAR_HARD_REG_SET (temp_hard_reg_set);
    else
      {
!       COPY_HARD_REG_SET (temp_hard_reg_set,
! 			 reg_class_contents[base_reg_class (VOIDmode, ADDRESS, SCRATCH)]);
        AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs);
        AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set);
      }
--- 788,800 ----
  	  ira_free (conflicts);
  	}
      }
! 
!   base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
!   if (! CLASS_LIKELY_SPILLED_P (base))
      CLEAR_HARD_REG_SET (temp_hard_reg_set);
    else
      {
!       COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[base]);
        AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs);
        AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set);
      }
Index: gcc/reload.c
===================================================================
*** gcc/reload.c	(revision 153564)
--- gcc/reload.c	(working copy)
*************** static int find_reloads_address (enum ma
*** 275,281 ****
  static rtx subst_reg_equivs (rtx, rtx);
  static rtx subst_indexed_address (rtx);
  static void update_auto_inc_notes (rtx, int, int);
! static int find_reloads_address_1 (enum machine_mode, rtx, int,
  				   enum rtx_code, enum rtx_code, rtx *,
  				   int, enum reload_type,int, rtx);
  static void find_reloads_address_part (rtx, rtx *, enum reg_class,
--- 275,281 ----
  static rtx subst_reg_equivs (rtx, rtx);
  static rtx subst_indexed_address (rtx);
  static void update_auto_inc_notes (rtx, int, int);
! static int find_reloads_address_1 (enum machine_mode, addr_space_t, rtx, int,
  				   enum rtx_code, enum rtx_code, rtx *,
  				   int, enum reload_type,int, rtx);
  static void find_reloads_address_part (rtx, rtx *, enum reg_class,
*************** find_reloads (rtx insn, int replace, int
*** 3227,3234 ****
  	      case 'p':
  		/* All necessary reloads for an address_operand
  		   were handled in find_reloads_address.  */
! 		this_alternative[i] = base_reg_class (VOIDmode, ADDRESS,
! 						      SCRATCH);
  		win = 1;
  		badop = 0;
  		break;
--- 3227,3235 ----
  	      case 'p':
  		/* All necessary reloads for an address_operand
  		   were handled in find_reloads_address.  */
! 		this_alternative[i]
! 		  = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
! 				    ADDRESS, SCRATCH);
  		win = 1;
  		badop = 0;
  		break;
*************** find_reloads (rtx insn, int replace, int
*** 3433,3441 ****
  
  			/* If we didn't already win, we can reload
  			   the address into a base register.  */
! 			this_alternative[i] = base_reg_class (VOIDmode,
! 							      ADDRESS,
! 							      SCRATCH);
  			badop = 0;
  			break;
  		      }
--- 3434,3442 ----
  
  			/* If we didn't already win, we can reload
  			   the address into a base register.  */
! 			this_alternative[i]
! 			  = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
! 					    ADDRESS, SCRATCH);
  			badop = 0;
  			break;
  		      }
*************** find_reloads (rtx insn, int replace, int
*** 3989,4006 ****
  	    /* If the address to be reloaded is a VOIDmode constant,
  	       use the default address mode as mode of the reload register,
  	       as would have been done by find_reloads_address.  */
  	    enum machine_mode address_mode;
  	    address_mode = GET_MODE (XEXP (recog_data.operand[i], 0));
  	    if (address_mode == VOIDmode)
! 	      {
! 		addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]);
! 		address_mode = targetm.addr_space.address_mode (as);
! 	      }
  
  	    operand_reloadnum[i]
  	      = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
  			     &XEXP (recog_data.operand[i], 0), (rtx*) 0,
! 			     base_reg_class (VOIDmode, MEM, SCRATCH),
  			     address_mode,
  			     VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
  	    rld[operand_reloadnum[i]].inc
--- 3990,4005 ----
  	    /* If the address to be reloaded is a VOIDmode constant,
  	       use the default address mode as mode of the reload register,
  	       as would have been done by find_reloads_address.  */
+ 	    addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]);
  	    enum machine_mode address_mode;
  	    address_mode = GET_MODE (XEXP (recog_data.operand[i], 0));
  	    if (address_mode == VOIDmode)
! 	      address_mode = targetm.addr_space.address_mode (as);
  
  	    operand_reloadnum[i]
  	      = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
  			     &XEXP (recog_data.operand[i], 0), (rtx*) 0,
! 			     base_reg_class (VOIDmode, as, MEM, SCRATCH),
  			     address_mode,
  			     VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
  	    rld[operand_reloadnum[i]].inc
*************** find_reloads_address (enum machine_mode 
*** 4897,4903 ****
        if (reg_equiv_constant[regno] != 0)
  	{
  	  find_reloads_address_part (reg_equiv_constant[regno], loc,
! 				     base_reg_class (mode, MEM, SCRATCH),
  				     GET_MODE (ad), opnum, type, ind_levels);
  	  return 1;
  	}
--- 4896,4902 ----
        if (reg_equiv_constant[regno] != 0)
  	{
  	  find_reloads_address_part (reg_equiv_constant[regno], loc,
! 				     base_reg_class (mode, as, MEM, SCRATCH),
  				     GET_MODE (ad), opnum, type, ind_levels);
  	  return 1;
  	}
*************** find_reloads_address (enum machine_mode 
*** 4960,4971 ****
  	 subject of a CLOBBER in this insn.  */
  
        else if (regno < FIRST_PSEUDO_REGISTER
! 	       && regno_ok_for_base_p (regno, mode, MEM, SCRATCH)
  	       && ! regno_clobbered_p (regno, this_insn, mode, 0))
  	return 0;
  
        /* If we do not have one of the cases above, we must do the reload.  */
!       push_reload (ad, NULL_RTX, loc, (rtx*) 0, base_reg_class (mode, MEM, SCRATCH),
  		   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
        return 1;
      }
--- 4959,4971 ----
  	 subject of a CLOBBER in this insn.  */
  
        else if (regno < FIRST_PSEUDO_REGISTER
! 	       && regno_ok_for_base_p (regno, mode, as, MEM, SCRATCH)
  	       && ! regno_clobbered_p (regno, this_insn, mode, 0))
  	return 0;
  
        /* If we do not have one of the cases above, we must do the reload.  */
!       push_reload (ad, NULL_RTX, loc, (rtx*) 0,
! 		   base_reg_class (mode, as, MEM, SCRATCH),
  		   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
        return 1;
      }
*************** find_reloads_address (enum machine_mode 
*** 5066,5072 ****
  	  /* Must use TEM here, not AD, since it is the one that will
  	     have any subexpressions reloaded, if needed.  */
  	  push_reload (tem, NULL_RTX, loc, (rtx*) 0,
! 		       base_reg_class (mode, MEM, SCRATCH), GET_MODE (tem),
  		       VOIDmode, 0,
  		       0, opnum, type);
  	  return ! removed_and;
--- 5066,5072 ----
  	  /* Must use TEM here, not AD, since it is the one that will
  	     have any subexpressions reloaded, if needed.  */
  	  push_reload (tem, NULL_RTX, loc, (rtx*) 0,
! 		       base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (tem),
  		       VOIDmode, 0,
  		       0, opnum, type);
  	  return ! removed_and;
*************** find_reloads_address (enum machine_mode 
*** 5084,5090 ****
  	   && REG_P (XEXP (ad, 0))
  	   && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
  	   && CONST_INT_P (XEXP (ad, 1))
! 	   && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, PLUS,
  				   CONST_INT))
  
      {
--- 5084,5090 ----
  	   && REG_P (XEXP (ad, 0))
  	   && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
  	   && CONST_INT_P (XEXP (ad, 1))
! 	   && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as, PLUS,
  				   CONST_INT))
  
      {
*************** find_reloads_address (enum machine_mode 
*** 5115,5121 ****
  	     reload the sum into a base reg.
  	     That will at least work.  */
  	  find_reloads_address_part (ad, loc,
! 				     base_reg_class (mode, MEM, SCRATCH),
  				     GET_MODE (ad), opnum, type, ind_levels);
  	}
        return ! removed_and;
--- 5115,5121 ----
  	     reload the sum into a base reg.
  	     That will at least work.  */
  	  find_reloads_address_part (ad, loc,
! 				     base_reg_class (mode, as, MEM, SCRATCH),
  				     GET_MODE (ad), opnum, type, ind_levels);
  	}
        return ! removed_and;
*************** find_reloads_address (enum machine_mode 
*** 5167,5173 ****
  
        addend = XEXP (XEXP (ad, 0), 1 - op_index);
  
!       if ((regno_ok_for_base_p (REGNO (operand), mode, inner_code,
  				GET_CODE (addend))
  	   || operand == frame_pointer_rtx
  #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
--- 5167,5173 ----
  
        addend = XEXP (XEXP (ad, 0), 1 - op_index);
  
!       if ((regno_ok_for_base_p (REGNO (operand), mode, as, inner_code,
  				GET_CODE (addend))
  	   || operand == frame_pointer_rtx
  #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
*************** find_reloads_address (enum machine_mode 
*** 5196,5206 ****
  				 op_index == 0 ? addend : offset_reg);
  	  *loc = ad;
  
! 	  cls = base_reg_class (mode, MEM, GET_CODE (addend));
  	  find_reloads_address_part (XEXP (ad, op_index), 
  				     &XEXP (ad, op_index), cls,
  				     GET_MODE (ad), opnum, type, ind_levels);
! 	  find_reloads_address_1 (mode,
  				  XEXP (ad, 1 - op_index), 1, GET_CODE (ad),
  				  GET_CODE (XEXP (ad, op_index)),
  				  &XEXP (ad, 1 - op_index), opnum,
--- 5196,5206 ----
  				 op_index == 0 ? addend : offset_reg);
  	  *loc = ad;
  
! 	  cls = base_reg_class (mode, as, MEM, GET_CODE (addend));
  	  find_reloads_address_part (XEXP (ad, op_index), 
  				     &XEXP (ad, op_index), cls,
  				     GET_MODE (ad), opnum, type, ind_levels);
! 	  find_reloads_address_1 (mode, as,
  				  XEXP (ad, 1 - op_index), 1, GET_CODE (ad),
  				  GET_CODE (XEXP (ad, op_index)),
  				  &XEXP (ad, 1 - op_index), opnum,
*************** find_reloads_address (enum machine_mode 
*** 5253,5265 ****
  	    loc = &XEXP (*loc, 0);
  	}
  
!       find_reloads_address_part (ad, loc, base_reg_class (mode, MEM, SCRATCH),
  				 address_mode, opnum, type, ind_levels);
        return ! removed_and;
      }
  
!   return find_reloads_address_1 (mode, ad, 0, MEM, SCRATCH, loc, opnum, type,
! 				 ind_levels, insn);
  }
  \f
  /* Find all pseudo regs appearing in AD
--- 5253,5266 ----
  	    loc = &XEXP (*loc, 0);
  	}
  
!       find_reloads_address_part (ad, loc,
! 				 base_reg_class (mode, as, MEM, SCRATCH),
  				 address_mode, opnum, type, ind_levels);
        return ! removed_and;
      }
  
!   return find_reloads_address_1 (mode, as, ad, 0, MEM, SCRATCH, loc,
! 				 opnum, type, ind_levels, insn);
  }
  \f
  /* Find all pseudo regs appearing in AD
*************** update_auto_inc_notes (rtx insn ATTRIBUT
*** 5492,5505 ****
     handles those cases gracefully.  */
  
  static int
! find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
  			enum rtx_code outer_code, enum rtx_code index_code,
  			rtx *loc, int opnum, enum reload_type type,
  			int ind_levels, rtx insn)
  {
! #define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, OUTER, INDEX)		\
    ((CONTEXT) == 0							\
!    ? regno_ok_for_base_p (REGNO, MODE, OUTER, INDEX)			\
     : REGNO_OK_FOR_INDEX_P (REGNO))					
  
    enum reg_class context_reg_class;
--- 5493,5507 ----
     handles those cases gracefully.  */
  
  static int
! find_reloads_address_1 (enum machine_mode mode, addr_space_t as,
! 			rtx x, int context,
  			enum rtx_code outer_code, enum rtx_code index_code,
  			rtx *loc, int opnum, enum reload_type type,
  			int ind_levels, rtx insn)
  {
! #define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, AS, OUTER, INDEX)	\
    ((CONTEXT) == 0							\
!    ? regno_ok_for_base_p (REGNO, MODE, AS, OUTER, INDEX)		\
     : REGNO_OK_FOR_INDEX_P (REGNO))					
  
    enum reg_class context_reg_class;
*************** find_reloads_address_1 (enum machine_mod
*** 5508,5514 ****
    if (context == 1)
      context_reg_class = INDEX_REG_CLASS;
    else
!     context_reg_class = base_reg_class (mode, outer_code, index_code);
  
    switch (code)
      {
--- 5510,5516 ----
    if (context == 1)
      context_reg_class = INDEX_REG_CLASS;
    else
!     context_reg_class = base_reg_class (mode, as, outer_code, index_code);
  
    switch (code)
      {
*************** find_reloads_address_1 (enum machine_mod
*** 5565,5574 ****
  	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
  	    || code0 == ZERO_EXTEND || code1 == MEM)
  	  {
! 	    find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
  				    &XEXP (x, 0), opnum, type, ind_levels,
  				    insn);
! 	    find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0,
  				    &XEXP (x, 1), opnum, type, ind_levels,
  				    insn);
  	  }
--- 5567,5576 ----
  	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
  	    || code0 == ZERO_EXTEND || code1 == MEM)
  	  {
! 	    find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH,
  				    &XEXP (x, 0), opnum, type, ind_levels,
  				    insn);
! 	    find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, code0,
  				    &XEXP (x, 1), opnum, type, ind_levels,
  				    insn);
  	  }
*************** find_reloads_address_1 (enum machine_mod
*** 5576,5631 ****
  	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
  		 || code1 == ZERO_EXTEND || code0 == MEM)
  	  {
! 	    find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1,
  				    &XEXP (x, 0), opnum, type, ind_levels,
  				    insn);
! 	    find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
  				    &XEXP (x, 1), opnum, type, ind_levels,
  				    insn);
  	  }
  
  	else if (code0 == CONST_INT || code0 == CONST
  		 || code0 == SYMBOL_REF || code0 == LABEL_REF)
! 	  find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0,
  				  &XEXP (x, 1), opnum, type, ind_levels,
  				  insn);
  
  	else if (code1 == CONST_INT || code1 == CONST
  		 || code1 == SYMBOL_REF || code1 == LABEL_REF)
! 	  find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1,
  				  &XEXP (x, 0), opnum, type, ind_levels,
  				  insn);
  
  	else if (code0 == REG && code1 == REG)
  	  {
  	    if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
! 		&& regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
  	      return 0;
  	    else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
! 		     && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
  	      return 0;
! 	    else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
! 	      find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
  				      &XEXP (x, 1), opnum, type, ind_levels,
  				      insn);
  	    else if (REGNO_OK_FOR_INDEX_P (REGNO (op1)))
! 	      find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
  				      &XEXP (x, 0), opnum, type, ind_levels,
  				      insn);
! 	    else if (regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
! 	      find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
  				      &XEXP (x, 0), opnum, type, ind_levels,
  				      insn);
  	    else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)))
! 	      find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
  				      &XEXP (x, 1), opnum, type, ind_levels,
  				      insn);
  	    else
  	      {
! 		find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
  					&XEXP (x, 0), opnum, type, ind_levels,
  					insn);
! 		find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
  					&XEXP (x, 1), opnum, type, ind_levels,
  					insn);
  	      }
--- 5578,5633 ----
  	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
  		 || code1 == ZERO_EXTEND || code0 == MEM)
  	  {
! 	    find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1,
  				    &XEXP (x, 0), opnum, type, ind_levels,
  				    insn);
! 	    find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
  				    &XEXP (x, 1), opnum, type, ind_levels,
  				    insn);
  	  }
  
  	else if (code0 == CONST_INT || code0 == CONST
  		 || code0 == SYMBOL_REF || code0 == LABEL_REF)
! 	  find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, code0,
  				  &XEXP (x, 1), opnum, type, ind_levels,
  				  insn);
  
  	else if (code1 == CONST_INT || code1 == CONST
  		 || code1 == SYMBOL_REF || code1 == LABEL_REF)
! 	  find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1,
  				  &XEXP (x, 0), opnum, type, ind_levels,
  				  insn);
  
  	else if (code0 == REG && code1 == REG)
  	  {
  	    if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
! 		&& regno_ok_for_base_p (REGNO (op0), mode, as, PLUS, REG))
  	      return 0;
  	    else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
! 		     && regno_ok_for_base_p (REGNO (op1), mode, as, PLUS, REG))
  	      return 0;
! 	    else if (regno_ok_for_base_p (REGNO (op0), mode, as, PLUS, REG))
! 	      find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
  				      &XEXP (x, 1), opnum, type, ind_levels,
  				      insn);
  	    else if (REGNO_OK_FOR_INDEX_P (REGNO (op1)))
! 	      find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG,
  				      &XEXP (x, 0), opnum, type, ind_levels,
  				      insn);
! 	    else if (regno_ok_for_base_p (REGNO (op1), mode, as, PLUS, REG))
! 	      find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH,
  				      &XEXP (x, 0), opnum, type, ind_levels,
  				      insn);
  	    else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)))
! 	      find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG,
  				      &XEXP (x, 1), opnum, type, ind_levels,
  				      insn);
  	    else
  	      {
! 		find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG,
  					&XEXP (x, 0), opnum, type, ind_levels,
  					insn);
! 		find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
  					&XEXP (x, 1), opnum, type, ind_levels,
  					insn);
  	      }
*************** find_reloads_address_1 (enum machine_mod
*** 5633,5652 ****
  
  	else if (code0 == REG)
  	  {
! 	    find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
  				    &XEXP (x, 0), opnum, type, ind_levels,
  				    insn);
! 	    find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
  				    &XEXP (x, 1), opnum, type, ind_levels,
  				    insn);
  	  }
  
  	else if (code1 == REG)
  	  {
! 	    find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
  				    &XEXP (x, 1), opnum, type, ind_levels,
  				    insn);
! 	    find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
  				    &XEXP (x, 0), opnum, type, ind_levels,
  				    insn);
  	  }
--- 5635,5654 ----
  
  	else if (code0 == REG)
  	  {
! 	    find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH,
  				    &XEXP (x, 0), opnum, type, ind_levels,
  				    insn);
! 	    find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG,
  				    &XEXP (x, 1), opnum, type, ind_levels,
  				    insn);
  	  }
  
  	else if (code1 == REG)
  	  {
! 	    find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
  				    &XEXP (x, 1), opnum, type, ind_levels,
  				    insn);
! 	    find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG,
  				    &XEXP (x, 0), opnum, type, ind_levels,
  				    insn);
  	  }
*************** find_reloads_address_1 (enum machine_mod
*** 5688,5694 ****
  	if ((REG_P (XEXP (op1, 1))
  	     && !REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
  	    || GET_CODE (XEXP (op1, 1)) == PLUS)
! 	  find_reloads_address_1 (mode, XEXP (op1, 1), 1, code, SCRATCH,
  				  &XEXP (op1, 1), opnum, RELOAD_OTHER,
  				  ind_levels, insn);
  
--- 5690,5696 ----
  	if ((REG_P (XEXP (op1, 1))
  	     && !REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
  	    || GET_CODE (XEXP (op1, 1)) == PLUS)
! 	  find_reloads_address_1 (mode, as, XEXP (op1, 1), 1, code, SCRATCH,
  				  &XEXP (op1, 1), opnum, RELOAD_OTHER,
  				  ind_levels, insn);
  
*************** find_reloads_address_1 (enum machine_mod
*** 5730,5737 ****
  		   register.  */
  		reloadnum = push_reload (tem, tem, &XEXP (x, 0),
  					 &XEXP (op1, 0),
! 					 base_reg_class (mode, code,
! 							 index_code),
  					 GET_MODE (x), GET_MODE (x), 0,
  					 0, opnum, RELOAD_OTHER);
  
--- 5732,5739 ----
  		   register.  */
  		reloadnum = push_reload (tem, tem, &XEXP (x, 0),
  					 &XEXP (op1, 0),
! 					 base_reg_class (mode, as,
! 							 code, index_code),
  					 GET_MODE (x), GET_MODE (x), 0,
  					 0, opnum, RELOAD_OTHER);
  
*************** find_reloads_address_1 (enum machine_mod
*** 5744,5754 ****
  	  regno = reg_renumber[regno];
  
  	/* We require a base register here...  */
! 	if (!regno_ok_for_base_p (regno, GET_MODE (x), code, index_code))
  	  {
  	    reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
  				     &XEXP (op1, 0), &XEXP (x, 0),
! 				     base_reg_class (mode, code, index_code),
  				     GET_MODE (x), GET_MODE (x), 0, 0,
  				     opnum, RELOAD_OTHER);
  
--- 5746,5757 ----
  	  regno = reg_renumber[regno];
  
  	/* We require a base register here...  */
! 	if (!regno_ok_for_base_p (regno, GET_MODE (x), as, code, index_code))
  	  {
  	    reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
  				     &XEXP (op1, 0), &XEXP (x, 0),
! 				     base_reg_class (mode, as,
! 						     code, index_code),
  				     GET_MODE (x), GET_MODE (x), 0, 0,
  				     opnum, RELOAD_OTHER);
  
*************** find_reloads_address_1 (enum machine_mod
*** 5814,5820 ****
  	  if (reg_renumber[regno] >= 0)
  	    regno = reg_renumber[regno];
  	  if (regno >= FIRST_PSEUDO_REGISTER
! 	      || !REG_OK_FOR_CONTEXT (context, regno, mode, code,
  				      index_code))
  	    {
  	      int reloadnum;
--- 5817,5823 ----
  	  if (reg_renumber[regno] >= 0)
  	    regno = reg_renumber[regno];
  	  if (regno >= FIRST_PSEUDO_REGISTER
! 	      || !REG_OK_FOR_CONTEXT (context, regno, mode, as, code,
  				      index_code))
  	    {
  	      int reloadnum;
*************** find_reloads_address_1 (enum machine_mod
*** 5886,5892 ****
  	 reloaded.  Targets that are better off reloading just either part
  	 (or perhaps even a different part of an outer expression), should
  	 define LEGITIMIZE_RELOAD_ADDRESS.  */
!       find_reloads_address_1 (GET_MODE (XEXP (x, 0)), XEXP (x, 0),
  			      context, code, SCRATCH, &XEXP (x, 0), opnum,
  			      type, ind_levels, insn);
        push_reload (x, NULL_RTX, loc, (rtx*) 0,
--- 5889,5895 ----
  	 reloaded.  Targets that are better off reloading just either part
  	 (or perhaps even a different part of an outer expression), should
  	 define LEGITIMIZE_RELOAD_ADDRESS.  */
!       find_reloads_address_1 (GET_MODE (XEXP (x, 0)), as, XEXP (x, 0),
  			      context, code, SCRATCH, &XEXP (x, 0), opnum,
  			      type, ind_levels, insn);
        push_reload (x, NULL_RTX, loc, (rtx*) 0,
*************** find_reloads_address_1 (enum machine_mod
*** 5957,5963 ****
  	  regno = reg_renumber[regno];
  
  	if (regno >= FIRST_PSEUDO_REGISTER
! 	    || !REG_OK_FOR_CONTEXT (context, regno, mode, outer_code,
  				    index_code))
  	  {
  	    push_reload (x, NULL_RTX, loc, (rtx*) 0,
--- 5960,5966 ----
  	  regno = reg_renumber[regno];
  
  	if (regno >= FIRST_PSEUDO_REGISTER
! 	    || !REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code,
  				    index_code))
  	  {
  	    push_reload (x, NULL_RTX, loc, (rtx*) 0,
*************** find_reloads_address_1 (enum machine_mod
*** 5990,5996 ****
  	    {
  	      int regno ATTRIBUTE_UNUSED = subreg_regno (x);
  
! 	      if (!REG_OK_FOR_CONTEXT (context, regno, mode, outer_code,
  				       index_code))
  		{
  		  push_reload (x, NULL_RTX, loc, (rtx*) 0,
--- 5993,5999 ----
  	    {
  	      int regno ATTRIBUTE_UNUSED = subreg_regno (x);
  
! 	      if (!REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code,
  				       index_code))
  		{
  		  push_reload (x, NULL_RTX, loc, (rtx*) 0,
*************** find_reloads_address_1 (enum machine_mod
*** 6031,6038 ****
  	if (fmt[i] == 'e')
  	  /* Pass SCRATCH for INDEX_CODE, since CODE can never be a PLUS once
  	     we get here.  */
! 	  find_reloads_address_1 (mode, XEXP (x, i), context, code, SCRATCH,
! 				  &XEXP (x, i), opnum, type, ind_levels, insn);
        }
    }
  
--- 6034,6042 ----
  	if (fmt[i] == 'e')
  	  /* Pass SCRATCH for INDEX_CODE, since CODE can never be a PLUS once
  	     we get here.  */
! 	  find_reloads_address_1 (mode, as, XEXP (x, i), context,
! 				  code, SCRATCH, &XEXP (x, i),
! 				  opnum, type, ind_levels, insn);
        }
    }
  
*************** find_reloads_subreg_address (rtx x, int 
*** 6203,6209 ****
  			(GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
  			 MEM_ADDR_SPACE (reg_equiv_mem[regno])))
  		push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
! 			     base_reg_class (GET_MODE (tem), MEM, SCRATCH),
  			     GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0,
  			     opnum, type);
  
--- 6207,6215 ----
  			(GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
  			 MEM_ADDR_SPACE (reg_equiv_mem[regno])))
  		push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
! 			     base_reg_class (GET_MODE (tem),
! 					     MEM_ADDR_SPACE (tem),
! 					     MEM, SCRATCH),
  			     GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0,
  			     opnum, type);
  
Index: gcc/caller-save.c
===================================================================
*** gcc/caller-save.c	(revision 153564)
--- gcc/caller-save.c	(working copy)
*************** init_caller_save (void)
*** 246,252 ****
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      if (TEST_HARD_REG_BIT
  	(reg_class_contents
! 	 [(int) base_reg_class (regno_save_mode[i][1], PLUS, CONST_INT)], i))
        break;
  
    gcc_assert (i < FIRST_PSEUDO_REGISTER);
--- 246,253 ----
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      if (TEST_HARD_REG_BIT
  	(reg_class_contents
! 	 [(int) base_reg_class (regno_save_mode[i][1], ADDR_SPACE_GENERIC,
! 				PLUS, CONST_INT)], i))
        break;
  
    gcc_assert (i < FIRST_PSEUDO_REGISTER);
Index: gcc/recog.c
===================================================================
*** gcc/recog.c	(revision 153564)
--- gcc/recog.c	(working copy)
*************** preprocess_constraints (void)
*** 2243,2249 ****
  		case 'p':
  		  op_alt[j].is_address = 1;
  		  op_alt[j].cl = reg_class_subunion[(int) op_alt[j].cl]
! 		      [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		  break;
  
  		case 'g':
--- 2243,2250 ----
  		case 'p':
  		  op_alt[j].is_address = 1;
  		  op_alt[j].cl = reg_class_subunion[(int) op_alt[j].cl]
! 		      [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
! 					     ADDRESS, SCRATCH)];
  		  break;
  
  		case 'g':
*************** preprocess_constraints (void)
*** 2264,2271 ****
  		      op_alt[j].cl
  			= (reg_class_subunion
  			   [(int) op_alt[j].cl]
! 			   [(int) base_reg_class (VOIDmode, ADDRESS,
! 						  SCRATCH)]);
  		      break;
  		    }
  
--- 2265,2272 ----
  		      op_alt[j].cl
  			= (reg_class_subunion
  			   [(int) op_alt[j].cl]
! 			   [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
! 						  ADDRESS, SCRATCH)]);
  		      break;
  		    }
  
Index: gcc/ira-costs.c
===================================================================
*** gcc/ira-costs.c	(revision 153564)
--- gcc/ira-costs.c	(working copy)
*************** record_reg_classes (int n_alts, int n_op
*** 398,404 ****
  		     base of an address, i.e. BASE_REG_CLASS.  */
  		  classes[i]
  		    = ira_reg_class_union[classes[i]]
! 		      [base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		  break;
  
  		case 'm':  case 'o':  case 'V':
--- 398,405 ----
  		     base of an address, i.e. BASE_REG_CLASS.  */
  		  classes[i]
  		    = ira_reg_class_union[classes[i]]
! 		      [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
! 				       ADDRESS, SCRATCH)];
  		  break;
  
  		case 'm':  case 'o':  case 'V':
*************** record_reg_classes (int n_alts, int n_op
*** 513,519 ****
  			 i.e. BASE_REG_CLASS.  */
  		      classes[i]
  			= ira_reg_class_union[classes[i]]
! 			  [base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		    }
  #endif
  		  break;
--- 514,521 ----
  			 i.e. BASE_REG_CLASS.  */
  		      classes[i]
  			= ira_reg_class_union[classes[i]]
! 			  [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
! 					   ADDRESS, SCRATCH)];
  		    }
  #endif
  		  break;
*************** ok_for_index_p_nonstrict (rtx reg)
*** 727,740 ****
     pseudo-registers should count as OK.  Arguments as for
     regno_ok_for_base_p.  */
  static inline bool
! ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode,
  			 enum rtx_code outer_code, enum rtx_code index_code)
  {
    unsigned regno = REGNO (reg);
  
    if (regno >= FIRST_PSEUDO_REGISTER)
      return true;
!   return ok_for_base_p_1 (regno, mode, outer_code, index_code);
  }
  
  /* Record the pseudo registers we must reload into hard registers in a
--- 729,742 ----
     pseudo-registers should count as OK.  Arguments as for
     regno_ok_for_base_p.  */
  static inline bool
! ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode, addr_space_t as,
  			 enum rtx_code outer_code, enum rtx_code index_code)
  {
    unsigned regno = REGNO (reg);
  
    if (regno >= FIRST_PSEUDO_REGISTER)
      return true;
!   return ok_for_base_p_1 (regno, mode, as, outer_code, index_code);
  }
  
  /* Record the pseudo registers we must reload into hard registers in a
*************** ok_for_base_p_nonstrict (rtx reg, enum m
*** 743,758 ****
     If CONTEXT is 0, we are looking at the base part of an address,
     otherwise we are looking at the index part.
  
!    MODE is the mode of the memory reference; OUTER_CODE and INDEX_CODE
!    give the context that the rtx appears in.  These three arguments
!    are passed down to base_reg_class.
  
     SCALE is twice the amount to multiply the cost by (it is twice so
     we can represent half-cost adjustments).  */
  static void
! record_address_regs (enum machine_mode mode, rtx x, int context,
! 		     enum rtx_code outer_code, enum rtx_code index_code,
! 		     int scale)
  {
    enum rtx_code code = GET_CODE (x);
    enum reg_class rclass;
--- 745,760 ----
     If CONTEXT is 0, we are looking at the base part of an address,
     otherwise we are looking at the index part.
  
!    MODE and AS are the mode and address space of the memory reference;
!    OUTER_CODE and INDEX_CODE give the context that the rtx appears in.
!    These four arguments are passed down to base_reg_class.
  
     SCALE is twice the amount to multiply the cost by (it is twice so
     we can represent half-cost adjustments).  */
  static void
! record_address_regs (enum machine_mode mode, addr_space_t as, rtx x,
! 		     int context, enum rtx_code outer_code,
! 		     enum rtx_code index_code, int scale)
  {
    enum rtx_code code = GET_CODE (x);
    enum reg_class rclass;
*************** record_address_regs (enum machine_mode m
*** 760,766 ****
    if (context == 1)
      rclass = INDEX_REG_CLASS;
    else
!     rclass = base_reg_class (mode, outer_code, index_code);
  
    switch (code)
      {
--- 762,768 ----
    if (context == 1)
      rclass = INDEX_REG_CLASS;
    else
!     rclass = base_reg_class (mode, as, outer_code, index_code);
  
    switch (code)
      {
*************** record_address_regs (enum machine_mode m
*** 799,865 ****
  	/* If this machine only allows one register per address, it
  	   must be in the first operand.  */
  	if (MAX_REGS_PER_ADDRESS == 1)
! 	  record_address_regs (mode, arg0, 0, PLUS, code1, scale);
  
  	/* If index and base registers are the same on this machine,
  	   just record registers in any non-constant operands.  We
  	   assume here, as well as in the tests below, that all
  	   addresses are in canonical form.  */
! 	else if (INDEX_REG_CLASS == base_reg_class (VOIDmode, PLUS, SCRATCH))
  	  {
! 	    record_address_regs (mode, arg0, context, PLUS, code1, scale);
  	    if (! CONSTANT_P (arg1))
! 	      record_address_regs (mode, arg1, context, PLUS, code0, scale);
  	  }
  
  	/* If the second operand is a constant integer, it doesn't
  	   change what class the first operand must be.  */
  	else if (code1 == CONST_INT || code1 == CONST_DOUBLE)
! 	  record_address_regs (mode, arg0, context, PLUS, code1, scale);
  	/* If the second operand is a symbolic constant, the first
  	   operand must be an index register.  */
  	else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF)
! 	  record_address_regs (mode, arg0, 1, PLUS, code1, scale);
  	/* If both operands are registers but one is already a hard
  	   register of index or reg-base class, give the other the
  	   class that the hard register is not.  */
  	else if (code0 == REG && code1 == REG
  		 && REGNO (arg0) < FIRST_PSEUDO_REGISTER
! 		 && (ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
  		     || ok_for_index_p_nonstrict (arg0)))
! 	  record_address_regs (mode, arg1,
! 			       ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
! 			       ? 1 : 0,
  			       PLUS, REG, scale);
  	else if (code0 == REG && code1 == REG
  		 && REGNO (arg1) < FIRST_PSEUDO_REGISTER
! 		 && (ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
  		     || ok_for_index_p_nonstrict (arg1)))
! 	  record_address_regs (mode, arg0,
! 			       ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
! 			       ? 1 : 0,
  			       PLUS, REG, scale);
  	/* If one operand is known to be a pointer, it must be the
  	   base with the other operand the index.  Likewise if the
  	   other operand is a MULT.  */
  	else if ((code0 == REG && REG_POINTER (arg0)) || code1 == MULT)
  	  {
! 	    record_address_regs (mode, arg0, 0, PLUS, code1, scale);
! 	    record_address_regs (mode, arg1, 1, PLUS, code0, scale);
  	  }
  	else if ((code1 == REG && REG_POINTER (arg1)) || code0 == MULT)
  	  {
! 	    record_address_regs (mode, arg0, 1, PLUS, code1, scale);
! 	    record_address_regs (mode, arg1, 0, PLUS, code0, scale);
  	  }
  	/* Otherwise, count equal chances that each might be a base or
  	   index register.  This case should be rare.  */
  	else
  	  {
! 	    record_address_regs (mode, arg0, 0, PLUS, code1, scale / 2);
! 	    record_address_regs (mode, arg0, 1, PLUS, code1, scale / 2);
! 	    record_address_regs (mode, arg1, 0, PLUS, code0, scale / 2);
! 	    record_address_regs (mode, arg1, 1, PLUS, code0, scale / 2);
  	  }
        }
        break;
--- 801,868 ----
  	/* If this machine only allows one register per address, it
  	   must be in the first operand.  */
  	if (MAX_REGS_PER_ADDRESS == 1)
! 	  record_address_regs (mode, as, arg0, 0, PLUS, code1, scale);
  
  	/* If index and base registers are the same on this machine,
  	   just record registers in any non-constant operands.  We
  	   assume here, as well as in the tests below, that all
  	   addresses are in canonical form.  */
! 	else if (INDEX_REG_CLASS
! 		 == base_reg_class (VOIDmode, as, PLUS, SCRATCH))
  	  {
! 	    record_address_regs (mode, as, arg0, context, PLUS, code1, scale);
  	    if (! CONSTANT_P (arg1))
! 	      record_address_regs (mode, as, arg1, context, PLUS, code0, scale);
  	  }
  
  	/* If the second operand is a constant integer, it doesn't
  	   change what class the first operand must be.  */
  	else if (code1 == CONST_INT || code1 == CONST_DOUBLE)
! 	  record_address_regs (mode, as, arg0, context, PLUS, code1, scale);
  	/* If the second operand is a symbolic constant, the first
  	   operand must be an index register.  */
  	else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF)
! 	  record_address_regs (mode, as, arg0, 1, PLUS, code1, scale);
  	/* If both operands are registers but one is already a hard
  	   register of index or reg-base class, give the other the
  	   class that the hard register is not.  */
  	else if (code0 == REG && code1 == REG
  		 && REGNO (arg0) < FIRST_PSEUDO_REGISTER
! 		 && (ok_for_base_p_nonstrict (arg0, mode, as, PLUS, REG)
  		     || ok_for_index_p_nonstrict (arg0)))
! 	  record_address_regs (mode, as, arg1,
! 			       ok_for_base_p_nonstrict (arg0, mode, as,
! 							PLUS, REG) ? 1 : 0,
  			       PLUS, REG, scale);
  	else if (code0 == REG && code1 == REG
  		 && REGNO (arg1) < FIRST_PSEUDO_REGISTER
! 		 && (ok_for_base_p_nonstrict (arg1, mode, as, PLUS, REG)
  		     || ok_for_index_p_nonstrict (arg1)))
! 	  record_address_regs (mode, as, arg0,
! 			       ok_for_base_p_nonstrict (arg1, mode, as,
! 							PLUS, REG) ? 1 : 0,
  			       PLUS, REG, scale);
  	/* If one operand is known to be a pointer, it must be the
  	   base with the other operand the index.  Likewise if the
  	   other operand is a MULT.  */
  	else if ((code0 == REG && REG_POINTER (arg0)) || code1 == MULT)
  	  {
! 	    record_address_regs (mode, as, arg0, 0, PLUS, code1, scale);
! 	    record_address_regs (mode, as, arg1, 1, PLUS, code0, scale);
  	  }
  	else if ((code1 == REG && REG_POINTER (arg1)) || code0 == MULT)
  	  {
! 	    record_address_regs (mode, as, arg0, 1, PLUS, code1, scale);
! 	    record_address_regs (mode, as, arg1, 0, PLUS, code0, scale);
  	  }
  	/* Otherwise, count equal chances that each might be a base or
  	   index register.  This case should be rare.  */
  	else
  	  {
! 	    record_address_regs (mode, as, arg0, 0, PLUS, code1, scale / 2);
! 	    record_address_regs (mode, as, arg0, 1, PLUS, code1, scale / 2);
! 	    record_address_regs (mode, as, arg1, 0, PLUS, code0, scale / 2);
! 	    record_address_regs (mode, as, arg1, 1, PLUS, code0, scale / 2);
  	  }
        }
        break;
*************** record_address_regs (enum machine_mode m
*** 869,878 ****
  	 up in the wrong place.  */
      case POST_MODIFY:
      case PRE_MODIFY:
!       record_address_regs (mode, XEXP (x, 0), 0, code,
  			   GET_CODE (XEXP (XEXP (x, 1), 1)), 2 * scale);
        if (REG_P (XEXP (XEXP (x, 1), 1)))
! 	record_address_regs (mode, XEXP (XEXP (x, 1), 1), 1, code, REG,
  			     2 * scale);
        break;
  
--- 872,881 ----
  	 up in the wrong place.  */
      case POST_MODIFY:
      case PRE_MODIFY:
!       record_address_regs (mode, as, XEXP (x, 0), 0, code,
  			   GET_CODE (XEXP (XEXP (x, 1), 1)), 2 * scale);
        if (REG_P (XEXP (XEXP (x, 1), 1)))
! 	record_address_regs (mode, as, XEXP (XEXP (x, 1), 1), 1, code, REG,
  			     2 * scale);
        break;
  
*************** record_address_regs (enum machine_mode m
*** 889,895 ****
  	  && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER)
  	in_inc_dec[COST_INDEX (REGNO (XEXP (x, 0)))] = true;
  #endif
!       record_address_regs (mode, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
        break;
  
      case REG:
--- 892,898 ----
  	  && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER)
  	in_inc_dec[COST_INDEX (REGNO (XEXP (x, 0)))] = true;
  #endif
!       record_address_regs (mode, as, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
        break;
  
      case REG:
*************** record_address_regs (enum machine_mode m
*** 920,926 ****
  	int i;
  	for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  	  if (fmt[i] == 'e')
! 	    record_address_regs (mode, XEXP (x, i), context, code, SCRATCH,
  				 scale);
        }
      }
--- 923,929 ----
  	int i;
  	for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  	  if (fmt[i] == 'e')
! 	    record_address_regs (mode, as, XEXP (x, i), context, code, SCRATCH,
  				 scale);
        }
      }
*************** record_operand_costs (rtx insn, struct c
*** 956,968 ****
  
        if (MEM_P (recog_data.operand[i]))
  	record_address_regs (GET_MODE (recog_data.operand[i]),
  			     XEXP (recog_data.operand[i], 0),
  			     0, MEM, SCRATCH, frequency * 2);
        else if (constraints[i][0] == 'p'
  	       || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0],
  					    constraints[i]))
! 	record_address_regs (VOIDmode, recog_data.operand[i], 0, ADDRESS,
! 			     SCRATCH, frequency * 2);
      }
  
    /* Check for commutative in a separate loop so everything will have
--- 959,973 ----
  
        if (MEM_P (recog_data.operand[i]))
  	record_address_regs (GET_MODE (recog_data.operand[i]),
+ 			     MEM_ADDR_SPACE (recog_data.operand[i]),
  			     XEXP (recog_data.operand[i], 0),
  			     0, MEM, SCRATCH, frequency * 2);
        else if (constraints[i][0] == 'p'
  	       || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0],
  					    constraints[i]))
! 	record_address_regs (VOIDmode, ADDR_SPACE_GENERIC,
! 			     recog_data.operand[i], 0, ADDRESS, SCRATCH,
! 			     frequency * 2);
      }
  
    /* Check for commutative in a separate loop so everything will have
*************** scan_one_insn (rtx insn)
*** 1028,1035 ****
  	cl = pref[num];
        COSTS (costs, num)->mem_cost
  	-= ira_memory_move_cost[GET_MODE (reg)][cl][1] * frequency;
!       record_address_regs (GET_MODE (SET_SRC (set)), XEXP (SET_SRC (set), 0),
! 			   0, MEM, SCRATCH, frequency * 2);
      }
  
    record_operand_costs (insn, op_costs, pref);
--- 1033,1042 ----
  	cl = pref[num];
        COSTS (costs, num)->mem_cost
  	-= ira_memory_move_cost[GET_MODE (reg)][cl][1] * frequency;
!       record_address_regs (GET_MODE (SET_SRC (set)),
! 			   MEM_ADDR_SPACE (SET_SRC (set)),
! 			   XEXP (SET_SRC (set), 0), 0, MEM, SCRATCH,
! 			   frequency * 2);
      }
  
    record_operand_costs (insn, op_costs, pref);
Index: gcc/addresses.h
===================================================================
*** gcc/addresses.h	(revision 153564)
--- gcc/addresses.h	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 23,33 ****
  
  static inline enum reg_class
  base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED,
  		enum rtx_code outer_code ATTRIBUTE_UNUSED,
  		enum rtx_code index_code ATTRIBUTE_UNUSED)
  {
  #ifdef MODE_CODE_BASE_REG_CLASS
!   return MODE_CODE_BASE_REG_CLASS (mode, outer_code, index_code);
  #else
  #ifdef MODE_BASE_REG_REG_CLASS
    if (index_code == REG)
--- 23,34 ----
  
  static inline enum reg_class
  base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED,
+ 		addr_space_t as ATTRIBUTE_UNUSED,
  		enum rtx_code outer_code ATTRIBUTE_UNUSED,
  		enum rtx_code index_code ATTRIBUTE_UNUSED)
  {
  #ifdef MODE_CODE_BASE_REG_CLASS
!   return MODE_CODE_BASE_REG_CLASS (mode, as, outer_code, index_code);
  #else
  #ifdef MODE_BASE_REG_REG_CLASS
    if (index_code == REG)
*************** base_reg_class (enum machine_mode mode A
*** 48,58 ****
  
  static inline bool
  ok_for_base_p_1 (unsigned regno, enum machine_mode mode ATTRIBUTE_UNUSED,
  		 enum rtx_code outer_code ATTRIBUTE_UNUSED,
  		 enum rtx_code index_code ATTRIBUTE_UNUSED)
  {
  #ifdef REGNO_MODE_CODE_OK_FOR_BASE_P
!   return REGNO_MODE_CODE_OK_FOR_BASE_P (regno, mode, outer_code, index_code);
  #else
  #ifdef REGNO_MODE_OK_FOR_REG_BASE_P
    if (index_code == REG)
--- 49,61 ----
  
  static inline bool
  ok_for_base_p_1 (unsigned regno, enum machine_mode mode ATTRIBUTE_UNUSED,
+ 		 addr_space_t as ATTRIBUTE_UNUSED,
  		 enum rtx_code outer_code ATTRIBUTE_UNUSED,
  		 enum rtx_code index_code ATTRIBUTE_UNUSED)
  {
  #ifdef REGNO_MODE_CODE_OK_FOR_BASE_P
!   return REGNO_MODE_CODE_OK_FOR_BASE_P (regno, mode, as,
! 					outer_code, index_code);
  #else
  #ifdef REGNO_MODE_OK_FOR_REG_BASE_P
    if (index_code == REG)
*************** ok_for_base_p_1 (unsigned regno, enum ma
*** 70,80 ****
     complete.  Arguments as for the called function.  */
  
  static inline bool
! regno_ok_for_base_p (unsigned regno, enum machine_mode mode,
  		     enum rtx_code outer_code, enum rtx_code index_code)
  {
    if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0)
      regno = reg_renumber[regno];
  
!   return ok_for_base_p_1 (regno, mode, outer_code, index_code);
  }
--- 73,83 ----
     complete.  Arguments as for the called function.  */
  
  static inline bool
! regno_ok_for_base_p (unsigned regno, enum machine_mode mode, addr_space_t as,
  		     enum rtx_code outer_code, enum rtx_code index_code)
  {
    if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0)
      regno = reg_renumber[regno];
  
!   return ok_for_base_p_1 (regno, mode, as, outer_code, index_code);
  }
Index: gcc/config/cris/cris.h
===================================================================
*** gcc/config/cris/cris.h	(revision 153564)
--- gcc/config/cris/cris.h	(working copy)
*************** enum reg_class
*** 578,584 ****
  
  #define BASE_REG_CLASS GENERAL_REGS
  
! #define MODE_CODE_BASE_REG_CLASS(MODE, OCODE, ICODE)	\
    ((OCODE) != POST_INC ? BASE_REG_CLASS : GENNONACR_REGS)
  
  #define INDEX_REG_CLASS GENERAL_REGS
--- 578,584 ----
  
  #define BASE_REG_CLASS GENERAL_REGS
  
! #define MODE_CODE_BASE_REG_CLASS(MODE, AS, OCODE, ICODE)	\
    ((OCODE) != POST_INC ? BASE_REG_CLASS : GENNONACR_REGS)
  
  #define INDEX_REG_CLASS GENERAL_REGS
*************** enum reg_class
*** 605,611 ****
  
  /* REGNO_OK_FOR_BASE_P seems to be obsolete wrt. this one, but not yet
     documented as such.  */
! #define REGNO_MODE_CODE_OK_FOR_BASE_P(REGNO, MODE, OCODE, ICODE)	\
   (REGNO_OK_FOR_BASE_P (REGNO)						\
    && ((OCODE) != POST_INC						\
        || !((REGNO) == CRIS_ACR_REGNUM					\
--- 605,611 ----
  
  /* REGNO_OK_FOR_BASE_P seems to be obsolete wrt. this one, but not yet
     documented as such.  */
! #define REGNO_MODE_CODE_OK_FOR_BASE_P(REGNO, MODE, AS, OCODE, ICODE)	\
   (REGNO_OK_FOR_BASE_P (REGNO)						\
    && ((OCODE) != POST_INC						\
        || !((REGNO) == CRIS_ACR_REGNUM					\
Index: gcc/config/bfin/bfin.h
===================================================================
*** gcc/config/bfin/bfin.h	(revision 153564)
--- gcc/config/bfin/bfin.h	(working copy)
*************** enum reg_class
*** 690,696 ****
     || (OUTER) == POST_DEC || (OUTER) == PRE_DEC		     \
     || (OUTER) == MEM || (OUTER) == ADDRESS)
  
! #define MODE_CODE_BASE_REG_CLASS(MODE, OUTER, INDEX)			\
    ((MODE) == HImode && IREG_POSSIBLE_P (OUTER) ? IPREGS : PREGS)
  
  #define INDEX_REG_CLASS         PREGS
--- 690,696 ----
     || (OUTER) == POST_DEC || (OUTER) == PRE_DEC		     \
     || (OUTER) == MEM || (OUTER) == ADDRESS)
  
! #define MODE_CODE_BASE_REG_CLASS(MODE, AS, OUTER, INDEX)	\
    ((MODE) == HImode && IREG_POSSIBLE_P (OUTER) ? IPREGS : PREGS)
  
  #define INDEX_REG_CLASS         PREGS
*************** enum reg_class
*** 705,714 ****
     || REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX))
  
  #ifdef REG_OK_STRICT
! #define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, OUTER, INDEX) \
    REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX)
  #else
! #define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, OUTER, INDEX) \
    REGNO_OK_FOR_BASE_NONSTRICT_P (X, MODE, OUTER, INDEX)
  #endif
  
--- 705,714 ----
     || REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX))
  
  #ifdef REG_OK_STRICT
! #define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, AS, OUTER, INDEX) \
    REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX)
  #else
! #define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, AS, OUTER, INDEX) \
    REGNO_OK_FOR_BASE_NONSTRICT_P (X, MODE, OUTER, INDEX)
  #endif
  
Index: gcc/regcprop.c
===================================================================
*** gcc/regcprop.c	(revision 153564)
--- gcc/regcprop.c	(working copy)
*************** static rtx find_oldest_value_reg (enum r
*** 82,88 ****
  static bool replace_oldest_value_reg (rtx *, enum reg_class, rtx,
  				      struct value_data *);
  static bool replace_oldest_value_addr (rtx *, enum reg_class,
! 				       enum machine_mode, rtx,
  				       struct value_data *);
  static bool replace_oldest_value_mem (rtx, rtx, struct value_data *);
  static bool copyprop_hardreg_forward_1 (basic_block, struct value_data *);
--- 82,88 ----
  static bool replace_oldest_value_reg (rtx *, enum reg_class, rtx,
  				      struct value_data *);
  static bool replace_oldest_value_addr (rtx *, enum reg_class,
! 				       enum machine_mode, addr_space_t, rtx,
  				       struct value_data *);
  static bool replace_oldest_value_mem (rtx, rtx, struct value_data *);
  static bool copyprop_hardreg_forward_1 (basic_block, struct value_data *);
*************** replace_oldest_value_reg (rtx *loc, enum
*** 462,469 ****
  
  static bool
  replace_oldest_value_addr (rtx *loc, enum reg_class cl,
! 			   enum machine_mode mode, rtx insn,
! 			   struct value_data *vd)
  {
    rtx x = *loc;
    RTX_CODE code = GET_CODE (x);
--- 462,469 ----
  
  static bool
  replace_oldest_value_addr (rtx *loc, enum reg_class cl,
! 			   enum machine_mode mode, addr_space_t as,
! 			   rtx insn, struct value_data *vd)
  {
    rtx x = *loc;
    RTX_CODE code = GET_CODE (x);
*************** replace_oldest_value_addr (rtx *loc, enu
*** 532,546 ****
  	    unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
  
  	    if (REGNO_OK_FOR_INDEX_P (regno1)
! 		&& regno_ok_for_base_p (regno0, mode, PLUS, REG))
  	      index_op = 1;
  	    else if (REGNO_OK_FOR_INDEX_P (regno0)
! 		     && regno_ok_for_base_p (regno1, mode, PLUS, REG))
  	      index_op = 0;
! 	    else if (regno_ok_for_base_p (regno0, mode, PLUS, REG)
  		     || REGNO_OK_FOR_INDEX_P (regno1))
  	      index_op = 1;
! 	    else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
  	      index_op = 0;
  	    else
  	      index_op = 1;
--- 532,546 ----
  	    unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
  
  	    if (REGNO_OK_FOR_INDEX_P (regno1)
! 		&& regno_ok_for_base_p (regno0, mode, as, PLUS, REG))
  	      index_op = 1;
  	    else if (REGNO_OK_FOR_INDEX_P (regno0)
! 		     && regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
  	      index_op = 0;
! 	    else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG)
  		     || REGNO_OK_FOR_INDEX_P (regno1))
  	      index_op = 1;
! 	    else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
  	      index_op = 0;
  	    else
  	      index_op = 1;
*************** replace_oldest_value_addr (rtx *loc, enu
*** 563,575 ****
  	  }
  
  	if (locI)
! 	  changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode,
! 						insn, vd);
  	if (locB)
  	  changed |= replace_oldest_value_addr (locB,
! 						base_reg_class (mode, PLUS,
  								index_code),
! 						mode, insn, vd);
  	return changed;
        }
  
--- 563,575 ----
  	  }
  
  	if (locI)
! 	  changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS,
! 						mode, as, insn, vd);
  	if (locB)
  	  changed |= replace_oldest_value_addr (locB,
! 						base_reg_class (mode, as, PLUS,
  								index_code),
! 						mode, as, insn, vd);
  	return changed;
        }
  
*************** replace_oldest_value_addr (rtx *loc, enu
*** 595,606 ****
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode,
  					      insn, vd);
        else if (fmt[i] == 'E')
  	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
  	  changed |= replace_oldest_value_addr (&XVECEXP (x, i, j), cl,
! 						mode, insn, vd);
      }
  
    return changed;
--- 595,606 ----
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode, as,
  					      insn, vd);
        else if (fmt[i] == 'E')
  	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
  	  changed |= replace_oldest_value_addr (&XVECEXP (x, i, j), cl,
! 						mode, as, insn, vd);
      }
  
    return changed;
*************** replace_oldest_value_mem (rtx x, rtx ins
*** 616,625 ****
    if (DEBUG_INSN_P (insn))
      cl = ALL_REGS;
    else
!     cl = base_reg_class (GET_MODE (x), MEM, SCRATCH);
  
    return replace_oldest_value_addr (&XEXP (x, 0), cl,
! 				    GET_MODE (x), insn, vd);
  }
  
  /* Perform the forward copy propagation on basic block BB.  */
--- 616,626 ----
    if (DEBUG_INSN_P (insn))
      cl = ALL_REGS;
    else
!     cl = base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x), MEM, SCRATCH);
  
    return replace_oldest_value_addr (&XEXP (x, 0), cl,
! 				    GET_MODE (x), MEM_ADDR_SPACE (x),
! 				    insn, vd);
  }
  
  /* Perform the forward copy propagation on basic block BB.  */
*************** copyprop_hardreg_forward_1 (basic_block 
*** 646,652 ****
  	      if (!VAR_LOC_UNKNOWN_P (loc)
  		  && replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn),
  						ALL_REGS, GET_MODE (loc),
! 						insn, vd))
  		{
  		  changed = apply_change_group ();
  		  gcc_assert (changed);
--- 647,653 ----
  	      if (!VAR_LOC_UNKNOWN_P (loc)
  		  && replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn),
  						ALL_REGS, GET_MODE (loc),
! 						ADDR_SPACE_GENERIC, insn, vd))
  		{
  		  changed = apply_change_group ();
  		  gcc_assert (changed);
*************** copyprop_hardreg_forward_1 (basic_block 
*** 790,796 ****
  		replaced[i]
  		  = replace_oldest_value_addr (recog_data.operand_loc[i],
  					       recog_op_alt[i][alt].cl,
! 					       VOIDmode, insn, vd);
  	      else if (REG_P (recog_data.operand[i]))
  		replaced[i]
  		  = replace_oldest_value_reg (recog_data.operand_loc[i],
--- 791,798 ----
  		replaced[i]
  		  = replace_oldest_value_addr (recog_data.operand_loc[i],
  					       recog_op_alt[i][alt].cl,
! 					       VOIDmode, ADDR_SPACE_GENERIC,
! 					       insn, vd);
  	      else if (REG_P (recog_data.operand[i]))
  		replaced[i]
  		  = replace_oldest_value_reg (recog_data.operand_loc[i],
Index: gcc/reload1.c
===================================================================
*** gcc/reload1.c	(revision 153564)
--- gcc/reload1.c	(working copy)
*************** maybe_fix_stack_asms (void)
*** 1535,1541 ****
  
  		case 'p':
  		  cls = (int) reg_class_subunion[cls]
! 		      [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		  break;
  
  		case 'g':
--- 1535,1542 ----
  
  		case 'p':
  		  cls = (int) reg_class_subunion[cls]
! 		      [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
! 					     ADDRESS, SCRATCH)];
  		  break;
  
  		case 'g':
*************** maybe_fix_stack_asms (void)
*** 1546,1552 ****
  		default:
  		  if (EXTRA_ADDRESS_CONSTRAINT (c, p))
  		    cls = (int) reg_class_subunion[cls]
! 		      [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		  else
  		    cls = (int) reg_class_subunion[cls]
  		      [(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
--- 1547,1554 ----
  		default:
  		  if (EXTRA_ADDRESS_CONSTRAINT (c, p))
  		    cls = (int) reg_class_subunion[cls]
! 		      [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
! 					     ADDRESS, SCRATCH)];
  		  else
  		    cls = (int) reg_class_subunion[cls]
  		      [(int) REG_CLASS_FROM_CONSTRAINT (c, p)];


-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

  reply	other threads:[~2009-10-29 18:32 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-15  4:17 m32c support for named addr spaces branch DJ Delorie
2009-10-15 18:07 ` Ulrich Weigand
2009-10-15 18:11   ` DJ Delorie
2009-10-16 14:19     ` Ulrich Weigand
2009-10-16 18:22       ` DJ Delorie
2009-10-16 22:05       ` DJ Delorie
2009-10-19 14:28         ` Ulrich Weigand
2009-10-19 14:36           ` Richard Guenther
2009-10-19 17:45             ` Ulrich Weigand
2009-10-19 20:57               ` DJ Delorie
2009-10-20  9:27                 ` Richard Guenther
2009-10-20 18:10                   ` DJ Delorie
2009-10-21 10:20                     ` Richard Guenther
2009-10-27 18:32                       ` Ulrich Weigand
2009-10-28 11:29                         ` Richard Guenther
2009-10-29 18:32                           ` Fix PR tree-optimization/41857 (Re: m32c support for named addr spaces branch) Ulrich Weigand
2009-10-30  9:51                             ` Richard Guenther
2009-11-02  9:38                               ` Zdenek Dvorak
2009-11-16 20:07                                 ` [patch] Fix regression (Re: Fix PR tree-optimization/41857) Ulrich Weigand
2009-11-17 15:40                                   ` Richard Guenther
2009-11-17 16:03                                     ` Zdenek Dvorak
2009-11-17 16:14                                       ` Richard Guenther
2009-11-17 16:29                                         ` Zdenek Dvorak
2009-11-17 16:31                                           ` Richard Guenther
2009-11-17 16:51                                             ` Zdenek Dvorak
2009-10-30 15:55                           ` m32c support for named addr spaces branch Ulrich Weigand
2009-10-16 23:57       ` DJ Delorie
2009-10-19 14:50         ` Ulrich Weigand
2009-10-29 18:37           ` Ulrich Weigand [this message]
2009-10-29 19:54             ` [patch] Address-space-aware base registers (Re: m32c support for named addr spaces branch) DJ Delorie
2009-10-29 20:18             ` DJ Delorie
2009-10-29 21:33               ` Ulrich Weigand
2009-10-29 22:50                 ` DJ Delorie
2009-10-30 14:51                   ` Ulrich Weigand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200910291832.n9TIWENj028460@d12av02.megacenter.de.ibm.com \
    --to=uweigand@de.ibm.com \
    --cc=dj@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).