This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [named address] ice-on-valid: in postreload.c:reload_cse_simplify_operands


Georg-Johann Lay wrote:
> Ulrich Weigand wrote:
> > This means that problems like the one you're seeing have been hidden
> > so far.  I've started looking into fixing this, but since I don't
> > have a target where this is needed, this effort never really went
> > anywhere.  I'll append below a patch I did a year or so ago; just
> > as something to look at, it probably will not even apply to the
> > current sources any more.
> 
> Sounds great that you tried to fix it!  Much work below... wow.
> 
> > I'd be happy to bring this up to date if you're willing to work with
> > me to get this tested on a target that needs this support ...

Here's an updated version of the patch that build with current GCC
mainline and passes the SPU test suite with no regressions.

Let me know if this works for you ...

Bye,
Ulrich


ChangeLog:

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

	* 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 177409)
--- gcc/regrename.c	(working copy)
*************** static void do_replace (struct du_head *
*** 138,144 ****
  static void scan_rtx_reg (rtx, rtx *, enum reg_class,
  			  enum scan_actions, enum op_type);
  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);
  static struct du_head *build_def_use (basic_block);
--- 138,145 ----
  static void scan_rtx_reg (rtx, rtx *, enum reg_class,
  			  enum scan_actions, enum op_type);
  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);
  static struct du_head *build_def_use (basic_block);
*************** scan_rtx_reg (rtx insn, rtx *loc, enum r
*** 778,784 ****
  
  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);
--- 779,786 ----
  
  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
*** 846,860 ****
  	    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;
--- 848,862 ----
  	    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
*** 877,886 ****
  	  }
  
  	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;
        }
--- 879,889 ----
  	  }
  
  	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
*** 900,907 ****
  
      case MEM:
        scan_rtx_address (insn, &XEXP (x, 0),
! 			base_reg_class (GET_MODE (x), MEM, SCRATCH), action,
! 			GET_MODE (x));
        return;
  
      case REG:
--- 903,911 ----
  
      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
*** 916,925 ****
    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);
      }
  }
  
--- 920,929 ----
    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
*** 952,959 ****
  
      case MEM:
        scan_rtx_address (insn, &XEXP (x, 0),
! 			base_reg_class (GET_MODE (x), MEM, SCRATCH), action,
! 			GET_MODE (x));
        return;
  
      case SET:
--- 956,964 ----
  
      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)
*** 1290,1296 ****
  		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);
  	    }
--- 1295,1302 ----
  		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);
  	    }
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi	(revision 177409)
--- gcc/doc/tm.texi	(working copy)
*************** register address.  You should define thi
*** 2453,2464 ****
  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
--- 2453,2465 ----
  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 
*** 2498,2505 ****
  @code{REGNO_MODE_CODE_OK_FOR_BASE_P}.
  @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
--- 2499,2509 ----
  @code{REGNO_MODE_CODE_OK_FOR_BASE_P}.
  @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/doc/tm.texi.in
===================================================================
*** gcc/doc/tm.texi.in	(revision 177409)
--- gcc/doc/tm.texi.in	(working copy)
*************** register address.  You should define thi
*** 2441,2452 ****
  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
--- 2441,2453 ----
  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 
*** 2486,2493 ****
  @code{REGNO_MODE_CODE_OK_FOR_BASE_P}.
  @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
--- 2487,2497 ----
  @code{REGNO_MODE_CODE_OK_FOR_BASE_P}.
  @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 177409)
--- gcc/ira-conflicts.c	(working copy)
*************** ira_debug_conflicts (bool reg_p)
*** 845,850 ****
--- 845,851 ----
  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)
*** 874,886 ****
  	  ira_free (conflicts);
  	}
      }
!   if (! targetm.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);
      }
--- 875,886 ----
  	  ira_free (conflicts);
  	}
      }
!   base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
!   if (! targetm.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 177409)
--- gcc/reload.c	(working copy)
*************** static int find_reloads_address (enum ma
*** 278,284 ****
  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,
--- 278,284 ----
  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
*** 3235,3242 ****
  	      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;
--- 3235,3243 ----
  	      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
*** 3441,3449 ****
  
  			/* 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;
  		      }
--- 3442,3450 ----
  
  			/* 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
*** 3973,3990 ****
  	    /* 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
--- 3974,3989 ----
  	    /* 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 
*** 4881,4887 ****
        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;
  	}
--- 4880,4886 ----
        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 
*** 4944,4955 ****
  	 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;
      }
--- 4943,4955 ----
  	 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 
*** 5050,5056 ****
  	  /* 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;
--- 5050,5056 ----
  	  /* 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 
*** 5068,5074 ****
  	   && 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)
  	       /* Similarly, if we were to reload the base register and the
  		  mem+offset address is still invalid, then we want to reload
--- 5068,5074 ----
  	   && 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)
  	       /* Similarly, if we were to reload the base register and the
  		  mem+offset address is still invalid, then we want to reload
*************** find_reloads_address (enum machine_mode 
*** 5087,5093 ****
  	}
  
        if (double_reg_address_ok
! 	  && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode,
  				  PLUS, CONST_INT))
  	{
  	  /* Unshare the sum as well.  */
--- 5087,5093 ----
  	}
  
        if (double_reg_address_ok
! 	  && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as,
  				  PLUS, CONST_INT))
  	{
  	  /* Unshare the sum as well.  */
*************** find_reloads_address (enum machine_mode 
*** 5106,5112 ****
  	     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;
--- 5106,5112 ----
  	     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 
*** 5158,5164 ****
  
        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 !HARD_FRAME_POINTER_IS_FRAME_POINTER
--- 5158,5164 ----
  
        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 !HARD_FRAME_POINTER_IS_FRAME_POINTER
*************** find_reloads_address (enum machine_mode 
*** 5187,5197 ****
  				 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,
--- 5187,5197 ----
  				 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 
*** 5244,5256 ****
  	    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);
  }
  
  /* Find all pseudo regs appearing in AD
--- 5244,5257 ----
  	    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);
  }
  
  /* Find all pseudo regs appearing in AD
*************** update_auto_inc_notes (rtx insn ATTRIBUT
*** 5483,5496 ****
     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;
--- 5484,5498 ----
     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
*** 5499,5505 ****
    if (context == 1)
      context_reg_class = INDEX_REG_CLASS;
    else
!     context_reg_class = base_reg_class (mode, outer_code, index_code);
  
    switch (code)
      {
--- 5501,5507 ----
    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
*** 5556,5565 ****
  	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);
  	  }
--- 5558,5567 ----
  	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
*** 5567,5622 ****
  	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);
  	      }
--- 5569,5624 ----
  	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
*** 5624,5643 ****
  
  	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);
  	  }
--- 5626,5645 ----
  
  	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
*** 5679,5685 ****
  	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);
  
--- 5681,5687 ----
  	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
*** 5721,5728 ****
  		   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);
  
--- 5723,5730 ----
  		   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
*** 5735,5745 ****
  	  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);
  
--- 5737,5748 ----
  	  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
*** 5805,5811 ****
  	  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;
--- 5808,5814 ----
  	  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
*** 5874,5880 ****
  	 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,
--- 5877,5883 ----
  	 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
*** 5945,5951 ****
  	  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,
--- 5948,5954 ----
  	  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
*** 5978,5984 ****
  	    {
  	      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,
--- 5981,5987 ----
  	    {
  	      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
*** 6019,6026 ****
  	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);
        }
    }
  
--- 6022,6030 ----
  	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 
*** 6197,6203 ****
  			 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);
  		  reloaded = 1;
--- 6201,6209 ----
  			 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);
  		  reloaded = 1;
Index: gcc/caller-save.c
===================================================================
*** gcc/caller-save.c	(revision 177409)
--- gcc/caller-save.c	(working copy)
*************** init_caller_save (void)
*** 231,237 ****
    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);
--- 231,238 ----
    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 177409)
--- gcc/recog.c	(working copy)
*************** preprocess_constraints (void)
*** 2259,2265 ****
  		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':
--- 2259,2266 ----
  		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)
*** 2280,2287 ****
  		      op_alt[j].cl
  			= (reg_class_subunion
  			   [(int) op_alt[j].cl]
! 			   [(int) base_reg_class (VOIDmode, ADDRESS,
! 						  SCRATCH)]);
  		      break;
  		    }
  
--- 2281,2288 ----
  		      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 177409)
--- gcc/ira-costs.c	(working copy)
*************** record_reg_classes (int n_alts, int n_op
*** 615,621 ****
  		     base of an address, i.e. BASE_REG_CLASS.  */
  		  classes[i]
  		    = ira_reg_class_subunion[classes[i]]
! 		      [base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		  break;
  
  		case 'm':  case 'o':  case 'V':
--- 615,622 ----
  		     base of an address, i.e. BASE_REG_CLASS.  */
  		  classes[i]
  		    = ira_reg_class_subunion[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
*** 730,736 ****
  			 i.e. BASE_REG_CLASS.  */
  		      classes[i]
  			= ira_reg_class_subunion[classes[i]]
! 			  [base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		    }
  #endif
  		  break;
--- 731,738 ----
  			 i.e. BASE_REG_CLASS.  */
  		      classes[i]
  			= ira_reg_class_subunion[classes[i]]
! 			  [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
! 					   ADDRESS, SCRATCH)];
  		    }
  #endif
  		  break;
*************** ok_for_index_p_nonstrict (rtx reg)
*** 974,987 ****
     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
--- 976,989 ----
     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
*** 990,1005 ****
     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;
--- 992,1007 ----
     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
*** 1007,1013 ****
    if (context == 1)
      rclass = INDEX_REG_CLASS;
    else
!     rclass = base_reg_class (mode, outer_code, index_code);
  
    switch (code)
      {
--- 1009,1015 ----
    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
*** 1046,1112 ****
  	/* 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;
--- 1048,1115 ----
  	/* 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
*** 1116,1125 ****
  	 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;
  
--- 1119,1128 ----
  	 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
*** 1130,1136 ****
        /* Double the importance of an allocno that is incremented or
  	 decremented, since it would take two extra insns if it ends
  	 up in the wrong place.  */
!       record_address_regs (mode, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
        break;
  
      case REG:
--- 1133,1139 ----
        /* Double the importance of an allocno that is incremented or
  	 decremented, since it would take two extra insns if it ends
  	 up in the wrong place.  */
!       record_address_regs (mode, as, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
        break;
  
      case REG:
*************** record_address_regs (enum machine_mode m
*** 1178,1184 ****
  	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);
        }
      }
--- 1181,1187 ----
  	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, enum reg
*** 1214,1226 ****
  
        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
--- 1217,1231 ----
  
        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)
*** 1294,1301 ****
  
        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);
        counted_mem = true;
      }
  
--- 1299,1308 ----
  
        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);
        counted_mem = true;
      }
  
Index: gcc/addresses.h
===================================================================
*** gcc/addresses.h	(revision 177409)
--- 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
*** 49,59 ****
  static inline bool
  ok_for_base_p_1 (unsigned regno ATTRIBUTE_UNUSED,
  		 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)
--- 50,62 ----
  static inline bool
  ok_for_base_p_1 (unsigned regno ATTRIBUTE_UNUSED,
  		 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 ATTRIBUT
*** 71,81 ****
     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);
  }
--- 74,84 ----
     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 177409)
--- gcc/config/cris/cris.h	(working copy)
*************** enum reg_class
*** 549,555 ****
  
  #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
--- 549,555 ----
  
  #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
*** 574,580 ****
  
  /* 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					\
--- 574,580 ----
  
  /* 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 177409)
--- gcc/config/bfin/bfin.h	(working copy)
*************** enum reg_class
*** 612,618 ****
     || (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
--- 612,618 ----
     || (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
*** 627,636 ****
     || 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
  
--- 627,636 ----
     || 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 177409)
--- gcc/regcprop.c	(working copy)
*************** static rtx find_oldest_value_reg (enum r
*** 98,104 ****
  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 *);
--- 98,104 ----
  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
*** 515,522 ****
  
  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);
--- 515,522 ----
  
  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
*** 585,599 ****
  	    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;
--- 585,599 ----
  	    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
*** 616,628 ****
  	  }
  
  	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;
        }
  
--- 616,628 ----
  	  }
  
  	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
*** 648,659 ****
    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;
--- 648,659 ----
    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
*** 669,678 ****
    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);
  }
  
  /* Apply all queued updates for DEBUG_INSNs that change some reg to
--- 669,679 ----
    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);
  }
  
  /* Apply all queued updates for DEBUG_INSNs that change some reg to
*************** copyprop_hardreg_forward_1 (basic_block 
*** 751,757 ****
  	      if (!VAR_LOC_UNKNOWN_P (loc))
  		replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn),
  					   ALL_REGS, GET_MODE (loc),
! 					   insn, vd);
  	    }
  
  	  if (insn == BB_END (bb))
--- 752,758 ----
  	      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);
  	    }
  
  	  if (insn == BB_END (bb))
*************** copyprop_hardreg_forward_1 (basic_block 
*** 893,899 ****
  		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],
--- 894,901 ----
  		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 177409)
--- gcc/reload1.c	(working copy)
*************** maybe_fix_stack_asms (void)
*** 1423,1429 ****
  
  		case 'p':
  		  cls = (int) reg_class_subunion[cls]
! 		      [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		  break;
  
  		case 'g':
--- 1423,1430 ----
  
  		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)
*** 1434,1440 ****
  		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)];
--- 1435,1442 ----
  		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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]