This is the mail archive of the gcc-patches@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]

RFA: new reload macro: MODE_BASE_REG_CLASS


Hi Guys,

  I would like to obtain permission to apply the following patch.  It
  creates a new macro for use by reload.  This macro, called
  MODE_BASE_REG_CLASS is a variant of the current BASE_REG_CLASS macro
  except that it allows the selection of the base register class in a
  mode dependent fashion.

  The patch was created by Bernd Schmidt some time ago, and I have
  recently found that it is needed by the ARM port in order to fix
  some code generation problems when it is running in THUMB mode.  In
  particular for the Thumb, the stack pointer is a valid base register
  for SI mode quantities but not QI or HI mode quantities.

  This patch fixes several unexpected failures in the gcc testsuite
  when running in the Thumb mode.

  OK to apply ?

Cheers
        Nick

2001-12-14  Nick Clifton  <nickc@cambridge.redhat.com>

	* reload.c (MODE_BASE_REG_CLASS): Provide default definition
	if one has not been supplied by the backend.
        (find_reloads): Use MODE_BASE_REG_CLASS instead of
	BASE_REG_CLASS.
        (find_reloads_address); Use MODE_BASE_REG_CLASS instead of
	BASE_REG_CLASS.
        (find_reloads_address_1); Use MODE_BASE_REG_CLASS instead of
	BASE_REG_CLASS.
        * doc/tm.texi: Document new MODE_BASE_REG_CLASS macro.
        * config/arm/arm.h (MODE_BASE_REG_CLASS): Define.

Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.172
diff -p -c -r1.172 reload.c
*** reload.c	2001/12/03 15:22:47	1.172
--- reload.c	2001/12/14 10:56:28
*************** a register with any other reload.  */
*** 114,119 ****
--- 114,123 ----
  #ifndef REG_MODE_OK_FOR_BASE_P
  #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
  #endif
+ 
+ #ifndef MODE_BASE_REG_CLASS
+ #define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
+ #endif
  
  /* All reloads of the current insn are recorded here.  See reload.h for
     comments.  */
*************** find_reloads (insn, replace, ind_levels,
*** 3029,3035 ****
  	      case 'p':
  		/* All necessary reloads for an address_operand
  		   were handled in find_reloads_address.  */
! 		this_alternative[i] = (int) BASE_REG_CLASS;
  		win = 1;
  		break;
  
--- 3033,3039 ----
  	      case 'p':
  		/* All necessary reloads for an address_operand
  		   were handled in find_reloads_address.  */
! 		this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
  		win = 1;
  		break;
  
*************** find_reloads (insn, replace, ind_levels,
*** 3686,3692 ****
  	    operand_reloadnum[i]
  	      = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
  			     &XEXP (recog_data.operand[i], 0), (rtx*)0,
! 			     BASE_REG_CLASS,
  			     GET_MODE (XEXP (recog_data.operand[i], 0)),
  			     VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
  	    rld[operand_reloadnum[i]].inc
--- 3690,3696 ----
  	    operand_reloadnum[i]
  	      = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
  			     &XEXP (recog_data.operand[i], 0), (rtx*)0,
! 			     MODE_BASE_REG_CLASS (VOIDmode),
  			     GET_MODE (XEXP (recog_data.operand[i], 0)),
  			     VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
  	    rld[operand_reloadnum[i]].inc
*************** find_reloads_address (mode, memrefloc, a
*** 4617,4623 ****
  	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,
  		   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
        return 1;
      }
--- 4621,4627 ----
  	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, MODE_BASE_REG_CLASS (mode),
  		   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
        return 1;
      }
*************** find_reloads_address (mode, memrefloc, a
*** 4718,4724 ****
  	  /* 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, GET_MODE (tem),
  		       VOIDmode, 0,
  		       0, opnum, type);
  	  return ! removed_and;
--- 4722,4728 ----
  	  /* 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,
! 		       MODE_BASE_REG_CLASS (mode), GET_MODE (tem),
  		       VOIDmode, 0,
  		       0, opnum, type);
  	  return ! removed_and;
*************** find_reloads_address (mode, memrefloc, a
*** 4764,4770 ****
  	  /* If the sum of two regs is not necessarily valid,
  	     reload the sum into a base reg.
  	     That will at least work.  */
! 	  find_reloads_address_part (ad, loc, BASE_REG_CLASS,
  				     Pmode, opnum, type, ind_levels);
  	}
        return ! removed_and;
--- 4768,4774 ----
  	  /* If the sum of two regs is not necessarily valid,
  	     reload the sum into a base reg.
  	     That will at least work.  */
! 	  find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
  				     Pmode, opnum, type, ind_levels);
  	}
        return ! removed_and;
*************** find_reloads_address (mode, memrefloc, a
*** 4807,4813 ****
  				plus_constant (XEXP (XEXP (ad, 0), 0),
  					       INTVAL (XEXP (ad, 1))),
  				XEXP (XEXP (ad, 0), 1));
!       find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0), BASE_REG_CLASS,
  				 GET_MODE (ad), opnum, type, ind_levels);
        find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
  			      type, 0, insn);
--- 4811,4818 ----
  				plus_constant (XEXP (XEXP (ad, 0), 0),
  					       INTVAL (XEXP (ad, 1))),
  				XEXP (XEXP (ad, 0), 1));
!       find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0),
! 				 MODE_BASE_REG_CLASS (mode),
  				 GET_MODE (ad), opnum, type, ind_levels);
        find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
  			      type, 0, insn);
*************** find_reloads_address (mode, memrefloc, a
*** 4831,4837 ****
  				XEXP (XEXP (ad, 0), 0),
  				plus_constant (XEXP (XEXP (ad, 0), 1),
  					       INTVAL (XEXP (ad, 1))));
!       find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1), BASE_REG_CLASS,
  				 GET_MODE (ad), opnum, type, ind_levels);
        find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
  			      type, 0, insn);
--- 4836,4843 ----
  				XEXP (XEXP (ad, 0), 0),
  				plus_constant (XEXP (XEXP (ad, 0), 1),
  					       INTVAL (XEXP (ad, 1))));
!       find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
! 				 MODE_BASE_REG_CLASS (mode),
  				 GET_MODE (ad), opnum, type, ind_levels);
        find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
  			      type, 0, insn);
*************** find_reloads_address (mode, memrefloc, a
*** 4877,4884 ****
  	    loc = &XEXP (*loc, 0);
  	}
  
!       find_reloads_address_part (ad, loc, BASE_REG_CLASS, Pmode, opnum, type,
! 				 ind_levels);
        return ! removed_and;
      }
  
--- 4883,4890 ----
  	    loc = &XEXP (*loc, 0);
  	}
  
!       find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
! 				 Pmode, opnum, type, ind_levels);
        return ! removed_and;
      }
  
*************** find_reloads_address_1 (mode, x, context
*** 5303,5309 ****
  		    /* Then reload the memory location into a base
  		       register.  */
  		    reloadnum = push_reload (tem, tem, &XEXP (x, 0),
! 					     &XEXP (op1, 0), BASE_REG_CLASS,
  					     GET_MODE (x), GET_MODE (x), 0,
  					     0, opnum, RELOAD_OTHER);
  
--- 5309,5316 ----
  		    /* Then reload the memory location into a base
  		       register.  */
  		    reloadnum = push_reload (tem, tem, &XEXP (x, 0),
! 					     &XEXP (op1, 0),
! 					     MODE_BASE_REG_CLASS (mode),
  					     GET_MODE (x), GET_MODE (x), 0,
  					     0, opnum, RELOAD_OTHER);
  
*************** find_reloads_address_1 (mode, x, context
*** 5320,5326 ****
  	      {
  		reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
  					 &XEXP (op1, 0), &XEXP (x, 0),
! 					 BASE_REG_CLASS,
  					 GET_MODE (x), GET_MODE (x), 0, 0,
  					 opnum, RELOAD_OTHER);
  
--- 5327,5333 ----
  	      {
  		reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
  					 &XEXP (op1, 0), &XEXP (x, 0),
! 					 MODE_BASE_REG_CLASS (mode),
  					 GET_MODE (x), GET_MODE (x), 0, 0,
  					 opnum, RELOAD_OTHER);
  
*************** find_reloads_address_1 (mode, x, context
*** 5421,5427 ****
  		  x = XEXP (x, 0);
  		  reloadnum
  		    = push_reload (x, x, loc, loc,
! 				   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
  				   GET_MODE (x), GET_MODE (x), 0, 0,
  				   opnum, RELOAD_OTHER);
  		}
--- 5428,5435 ----
  		  x = XEXP (x, 0);
  		  reloadnum
  		    = push_reload (x, x, loc, loc,
! 				   (context ? INDEX_REG_CLASS :
! 				    MODE_BASE_REG_CLASS (mode)),
  				   GET_MODE (x), GET_MODE (x), 0, 0,
  				   opnum, RELOAD_OTHER);
  		}
*************** find_reloads_address_1 (mode, x, context
*** 5429,5435 ****
  		{
  		  reloadnum
  		    = push_reload (x, NULL_RTX, loc, (rtx*)0,
! 				   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
  				   GET_MODE (x), GET_MODE (x), 0, 0,
  				   opnum, type);
  		  rld[reloadnum].inc
--- 5437,5444 ----
  		{
  		  reloadnum
  		    = push_reload (x, NULL_RTX, loc, (rtx*)0,
! 				   (context ? INDEX_REG_CLASS :
! 				    MODE_BASE_REG_CLASS (mode)),
  				   GET_MODE (x), GET_MODE (x), 0, 0,
  				   opnum, type);
  		  rld[reloadnum].inc
*************** find_reloads_address_1 (mode, x, context
*** 5469,5475 ****
  				opnum, type, ind_levels, insn);
  
  	  reloadnum = push_reload (x, NULL_RTX, loc, (rtx*)0,
! 				   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
  				   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	  rld[reloadnum].inc
  	    = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
--- 5478,5485 ----
  				opnum, type, ind_levels, insn);
  
  	  reloadnum = push_reload (x, NULL_RTX, loc, (rtx*)0,
! 				   (context ? INDEX_REG_CLASS :
! 				    MODE_BASE_REG_CLASS (mode)),
  				   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	  rld[reloadnum].inc
  	    = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
*************** find_reloads_address_1 (mode, x, context
*** 5498,5504 ****
        find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
  			    opnum, ADDR_TYPE (type), ind_levels, insn);
        push_reload (*loc, NULL_RTX, loc, (rtx*)0,
! 		   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
  		   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
        return 1;
  
--- 5508,5514 ----
        find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
  			    opnum, ADDR_TYPE (type), ind_levels, insn);
        push_reload (*loc, NULL_RTX, loc, (rtx*)0,
! 		   (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
  		   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
        return 1;
  
*************** find_reloads_address_1 (mode, x, context
*** 5509,5515 ****
  	if (reg_equiv_constant[regno] != 0)
  	  {
  	    find_reloads_address_part (reg_equiv_constant[regno], loc,
! 				       (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
  				       GET_MODE (x), opnum, type, ind_levels);
  	    return 1;
  	  }
--- 5519,5526 ----
  	if (reg_equiv_constant[regno] != 0)
  	  {
  	    find_reloads_address_part (reg_equiv_constant[regno], loc,
! 				       (context ? INDEX_REG_CLASS :
! 					MODE_BASE_REG_CLASS (mode)),
  				       GET_MODE (x), opnum, type, ind_levels);
  	    return 1;
  	  }
*************** find_reloads_address_1 (mode, x, context
*** 5519,5525 ****
  	if (reg_equiv_mem[regno] != 0)
  	  {
  	    push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*)0,
! 			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
  			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	    return 1;
  	  }
--- 5530,5537 ----
  	if (reg_equiv_mem[regno] != 0)
  	  {
  	    push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*)0,
! 			 (context ? INDEX_REG_CLASS :
! 			  MODE_BASE_REG_CLASS (mode)),
  			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	    return 1;
  	  }
*************** find_reloads_address_1 (mode, x, context
*** 5547,5553 ****
  		  : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
  	  {
  	    push_reload (x, NULL_RTX, loc, (rtx*)0,
! 			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
  			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	    return 1;
  	  }
--- 5559,5565 ----
  		  : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
  	  {
  	    push_reload (x, NULL_RTX, loc, (rtx*)0,
! 			 (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
  			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	    return 1;
  	  }
*************** find_reloads_address_1 (mode, x, context
*** 5559,5565 ****
  	if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
  	  {
  	    push_reload (x, NULL_RTX, loc, (rtx*)0,
! 			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
  			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	    return 1;
  	  }
--- 5571,5577 ----
  	if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
  	  {
  	    push_reload (x, NULL_RTX, loc, (rtx*)0,
! 			 (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
  			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	    return 1;
  	  }
*************** find_reloads_address_1 (mode, x, context
*** 5580,5586 ****
  		     : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
  		{
  		  push_reload (x, NULL_RTX, loc, (rtx*)0,
! 			       (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
  			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  		  return 1;
  		}
--- 5592,5599 ----
  		     : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
  		{
  		  push_reload (x, NULL_RTX, loc, (rtx*)0,
! 			       (context ? INDEX_REG_CLASS :
! 				MODE_BASE_REG_CLASS (mode)),
  			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  		  return 1;
  		}
*************** find_reloads_address_1 (mode, x, context
*** 5590,5596 ****
  	  else
  	    {
  	      enum reg_class class = (context ? INDEX_REG_CLASS
! 				      : BASE_REG_CLASS);
  	      if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
  		  > reg_class_size[class])
  		{
--- 5603,5609 ----
  	  else
  	    {
  	      enum reg_class class = (context ? INDEX_REG_CLASS
! 				      : MODE_BASE_REG_CLASS (mode));
  	      if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
  		  > reg_class_size[class])
  		{

Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.79
diff -p -c -r1.79 tm.texi
*** tm.texi	2001/12/13 14:24:03	1.79
--- tm.texi	2001/12/14 10:56:31
*************** A macro whose definition is the name of 
*** 2203,2208 ****
--- 2203,2213 ----
  base register must belong.  A base register is one used in an address
  which is the register value plus a displacement.
  
+ @findex MODE_BASE_REG_CLASS
+ @item MODE_BASE_REG_CLASS (@var{mode})
+ This is a variation of the @code{BASE_REG_CLASS} macro which allows
+ the selection of a base register in a mode depenedent manner.
+ 
  @findex INDEX_REG_CLASS
  @item INDEX_REG_CLASS
  A macro whose definition is the name of the class to which a valid

Index: gcc/config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.127
diff -p -c -r1.127 arm.h
*** arm.h	2001/12/13 00:27:30	1.127
--- arm.h	2001/12/14 10:56:32
*************** enum reg_class
*** 1099,1104 ****
--- 1099,1111 ----
  #define INDEX_REG_CLASS  (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
  #define BASE_REG_CLASS   (TARGET_THUMB ? BASE_REGS : GENERAL_REGS)
  
+ /* For the Thumb the high registers cannot be used as base
+    registers when addressing quanitities in QI or HI mode.  */
+ #define MODE_BASE_REG_CLASS(MODE)		\
+     (TARGET_ARM ? BASE_REGS :			\
+      (((MODE) != QImode && (MODE) != HImode)	\
+      ? BASE_REGS : LO_REGS))
+ 
  /* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
     registers explicitly used in the rtl to be used as spill registers
     but prevents the compiler from extending the lifetime of these



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