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]

[PATCH] Target macro to redefine 'm' constraint letter


Hello,

as discussed in the mail-thread starting with:
http://gcc.gnu.org/ml/gcc-patches/2007-10/msg01407.html
it might be necessary to override the meaning of the 'm' constraint
when adding new address formats to the GO_IF_LEGITIMATE_ADDRESS_P
hook.

The attached patch implements the suggestion from Richard Sandiford.
A new target macro called TARGET_MEM_CONSTRAINT is introduced which
allows to change the constraint letter used for the addresses matched
by the legitimate address hook.  That way it is possible to extend the
set of accepted addresses in the hook without changing the semantics of
the 'm' constraint what would be fatal for inline assemblies using
that constraint.

Another solution might be to provide a more general mechanism letting
back ends override all standard constraints.  The middle-end would
just provide default implementations which might be replaced in a back
end by using the standard constraint definition mechanism:
http://gcc.gnu.org/ml/gcc-patches/2007-11/msg00319.html

Since I never got a response to that I've decided to go with Richards
suggestion in order to have at least one supporter ;)

This change currently is a nop for all architectures.

Boostrapped and reg-tested on s390x and i686.

Ok for mainline?

Bye,

-Andreas-

2008-03-20  Andreas Krebbel  <krebbel1@de.ibm.com>

	* defaults.h (TARGET_MEM_CONSTRAINT): New target macro added.
	* postreload.c (reload_cse_simplify_operands): Replace 'm'
	constraint with TARGET_MEM_CONSTRAINT.
	* recog.c (asm_operand_ok, preprocess_constraints,
	constrain_operands): Likewise.
	* regclass.c (record_reg_classes): Likewise.
	* reload.c (find_reloads, alternative_allows_const_pool_ref):
	Likewise.
	* reload1.c (maybe_fix_stack_asms): Likewise.
	* stmt.c (parse_output_constraint, parse_input_constraint):
	Likewise.
	* recog.h: Adjust comment.
	* genpreds.c (generic_constraint_letters): Remove 'm' constraint.
	* genoutput.c (note_constraint): Don't emit error for 'm'
	constraint.
	* doc/md.texi: Add a note to description of 'm' constraint.
	* doc/tm.texi: Document the new TARGET_MEM_CONSTRAINT macro.


Index: gcc/defaults.h
===================================================================
*** gcc/defaults.h.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/defaults.h	2008-03-20 14:55:43.000000000 +0100
*************** along with GCC; see the file COPYING3.  
*** 902,907 ****
--- 902,911 ----
  #define LEGITIMATE_PIC_OPERAND_P(X) 1
  #endif
  
+ #ifndef TARGET_MEM_CONSTRAINT
+ #define TARGET_MEM_CONSTRAINT 'm'
+ #endif
+ 
  #ifndef REVERSIBLE_CC_MODE
  #define REVERSIBLE_CC_MODE(MODE) 0
  #endif
Index: gcc/postreload.c
===================================================================
*** gcc/postreload.c.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/postreload.c	2008-03-20 14:55:43.000000000 +0100
*************** reload_cse_simplify_operands (rtx insn, 
*** 542,553 ****
  		case '*':  case '%':
  		case '0':  case '1':  case '2':  case '3':  case '4':
  		case '5':  case '6':  case '7':  case '8':  case '9':
! 		case 'm':  case '<':  case '>':  case 'V':  case 'o':
  		case 'E':  case 'F':  case 'G':  case 'H':
  		case 's':  case 'i':  case 'n':
  		case 'I':  case 'J':  case 'K':  case 'L':
  		case 'M':  case 'N':  case 'O':  case 'P':
! 		case 'p': case 'X':
  		  /* These don't say anything we care about.  */
  		  break;
  
--- 542,553 ----
  		case '*':  case '%':
  		case '0':  case '1':  case '2':  case '3':  case '4':
  		case '5':  case '6':  case '7':  case '8':  case '9':
! 		case '<':  case '>':  case 'V':  case 'o':
  		case 'E':  case 'F':  case 'G':  case 'H':
  		case 's':  case 'i':  case 'n':
  		case 'I':  case 'J':  case 'K':  case 'L':
  		case 'M':  case 'N':  case 'O':  case 'P':
! 		case 'p':  case 'X':  case TARGET_MEM_CONSTRAINT:
  		  /* These don't say anything we care about.  */
  		  break;
  
Index: gcc/recog.c
===================================================================
*** gcc/recog.c.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/recog.c	2008-03-20 15:20:59.000000000 +0100
*************** asm_operand_ok (rtx op, const char *cons
*** 1543,1549 ****
  	    result = 1;
  	  break;
  
! 	case 'm':
  	case 'V': /* non-offsettable */
  	  if (memory_operand (op, VOIDmode))
  	    result = 1;
--- 1543,1549 ----
  	    result = 1;
  	  break;
  
! 	case TARGET_MEM_CONSTRAINT:
  	case 'V': /* non-offsettable */
  	  if (memory_operand (op, VOIDmode))
  	    result = 1;
*************** preprocess_constraints (void)
*** 2082,2088 ****
  		  }
  		  continue;
  
! 		case 'm':
  		  op_alt[j].memory_ok = 1;
  		  break;
  		case '<':
--- 2082,2088 ----
  		  }
  		  continue;
  
! 		case TARGET_MEM_CONSTRAINT:
  		  op_alt[j].memory_ok = 1;
  		  break;
  		case '<':
*************** constrain_operands (int strict)
*** 2355,2361 ****
  		win = 1;
  		break;
  
! 	      case 'm':
  		/* Memory operands must be valid, to the extent
  		   required by STRICT.  */
  		if (MEM_P (op))
--- 2355,2361 ----
  		win = 1;
  		break;
  
! 	      case TARGET_MEM_CONSTRAINT:
  		/* Memory operands must be valid, to the extent
  		   required by STRICT.  */
  		if (MEM_P (op))
Index: gcc/regclass.c
===================================================================
*** gcc/regclass.c.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/regclass.c	2008-03-20 14:55:43.000000000 +0100
*************** record_reg_classes (int n_alts, int n_op
*** 1701,1707 ****
  		    [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		  break;
  
! 		case 'm':  case 'o':  case 'V':
  		  /* It doesn't seem worth distinguishing between offsettable
  		     and non-offsettable addresses here.  */
  		  allows_mem[i] = 1;
--- 1701,1707 ----
  		    [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
  		  break;
  
! 		case TARGET_MEM_CONSTRAINT:  case 'o':  case 'V':
  		  /* It doesn't seem worth distinguishing between offsettable
  		     and non-offsettable addresses here.  */
  		  allows_mem[i] = 1;
Index: gcc/reload.c
===================================================================
*** gcc/reload.c.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/reload.c	2008-03-20 15:20:59.000000000 +0100
*************** find_reloads (rtx insn, int replace, int
*** 3180,3186 ****
  		badop = 0;
  		break;
  
! 	      case 'm':
  		if (force_reload)
  		  break;
  		if (MEM_P (operand)
--- 3180,3186 ----
  		badop = 0;
  		break;
  
! 	      case TARGET_MEM_CONSTRAINT:
  		if (force_reload)
  		  break;
  		if (MEM_P (operand)
*************** alternative_allows_const_pool_ref (rtx m
*** 4520,4526 ****
        while (*constraint++ != ',');
        altnum--;
      }
!   /* Scan the requested alternative for 'm' or 'o'.
       If one of them is present, this alternative accepts the result of
       passing a constant-pool reference through find_reloads_toplev.
  
--- 4520,4526 ----
        while (*constraint++ != ',');
        altnum--;
      }
!   /* Scan the requested alternative for TARGET_MEM_CONSTRAINT or 'o'.
       If one of them is present, this alternative accepts the result of
       passing a constant-pool reference through find_reloads_toplev.
  
*************** alternative_allows_const_pool_ref (rtx m
*** 4531,4537 ****
    for (; (c = *constraint) && c != ',' && c != '#';
         constraint += CONSTRAINT_LEN (c, constraint))
      {
!       if (c == 'm' || c == 'o')
  	return true;
  #ifdef EXTRA_CONSTRAINT_STR
        if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
--- 4531,4537 ----
    for (; (c = *constraint) && c != ',' && c != '#';
         constraint += CONSTRAINT_LEN (c, constraint))
      {
!       if (c == TARGET_MEM_CONSTRAINT || c == 'o')
  	return true;
  #ifdef EXTRA_CONSTRAINT_STR
        if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
Index: gcc/reload1.c
===================================================================
*** gcc/reload1.c.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/reload1.c	2008-03-20 14:55:43.000000000 +0100
*************** maybe_fix_stack_asms (void)
*** 1455,1465 ****
  	      switch (c)
  		{
  		case '=': case '+': case '*': case '%': case '?': case '!':
! 		case '0': case '1': case '2': case '3': case '4': case 'm':
! 		case '<': case '>': case 'V': case 'o': case '&': case 'E':
! 		case 'F': case 's': case 'i': case 'n': case 'X': case 'I':
! 		case 'J': case 'K': case 'L': case 'M': case 'N': case 'O':
! 		case 'P':
  		  break;
  
  		case 'p':
--- 1455,1465 ----
  	      switch (c)
  		{
  		case '=': case '+': case '*': case '%': case '?': case '!':
! 		case '0': case '1': case '2': case '3': case '4': case '<':
! 		case '>': case 'V': case 'o': case '&': case 'E': case 'F':
! 		case 's': case 'i': case 'n': case 'X': case 'I': case 'J':
! 		case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
! 		case TARGET_MEM_CONSTRAINT:
  		  break;
  
  		case 'p':
Index: gcc/stmt.c
===================================================================
*** gcc/stmt.c.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/stmt.c	2008-03-20 14:55:43.000000000 +0100
*************** parse_output_constraint (const char **co
*** 364,370 ****
  	  }
  	break;
  
!       case 'V':  case 'm':  case 'o':
  	*allows_mem = true;
  	break;
  
--- 364,370 ----
  	  }
  	break;
  
!       case 'V':  case TARGET_MEM_CONSTRAINT:  case 'o':
  	*allows_mem = true;
  	break;
  
*************** parse_input_constraint (const char **con
*** 463,469 ****
  	  }
  	break;
  
!       case 'V':  case 'm':  case 'o':
  	*allows_mem = true;
  	break;
  
--- 463,469 ----
  	  }
  	break;
  
!       case 'V':  case TARGET_MEM_CONSTRAINT:  case 'o':
  	*allows_mem = true;
  	break;
  
Index: gcc/recog.h
===================================================================
*** gcc/recog.h.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/recog.h	2008-03-20 15:20:59.000000000 +0100
*************** struct operand_alternative
*** 50,56 ****
  
    /* Nonzero if '&' was found in the constraint string.  */
    unsigned int earlyclobber:1;
!   /* Nonzero if 'm' was found in the constraint string.  */
    unsigned int memory_ok:1;
    /* Nonzero if 'o' was found in the constraint string.  */
    unsigned int offmem_ok:1;
--- 50,57 ----
  
    /* Nonzero if '&' was found in the constraint string.  */
    unsigned int earlyclobber:1;
!   /* Nonzero if TARGET_MEM_CONSTRAINT was found in the constraint
!      string.  */
    unsigned int memory_ok:1;
    /* Nonzero if 'o' was found in the constraint string.  */
    unsigned int offmem_ok:1;
Index: gcc/genpreds.c
===================================================================
*** gcc/genpreds.c.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/genpreds.c	2008-03-20 14:55:43.000000000 +0100
*************** static struct constraint_data **last_con
*** 690,697 ****
    for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
  
  /* These letters, and all names beginning with them, are reserved for
!    generic constraints.  */
! static const char generic_constraint_letters[] = "EFVXgimnoprs";
  
  /* Machine-independent code expects that constraints with these
     (initial) letters will allow only (a subset of all) CONST_INTs.  */
--- 690,700 ----
    for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
  
  /* These letters, and all names beginning with them, are reserved for
!    generic constraints.
!    The 'm' constraint is not mentioned here since that constraint
!    letter can be overridden by the back end by defining the
!    TARGET_MEM_CONSTRAINT macro.  */
! static const char generic_constraint_letters[] = "EFVXginoprs";
  
  /* Machine-independent code expects that constraints with these
     (initial) letters will allow only (a subset of all) CONST_INTs.  */
Index: gcc/genoutput.c
===================================================================
*** gcc/genoutput.c.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/genoutput.c	2008-03-20 15:20:26.000000000 +0100
*************** note_constraint (rtx exp, int lineno)
*** 1122,1128 ****
    unsigned int namelen = strlen (name);
    struct constraint_data **iter, **slot, *new;
  
!   if (strchr (indep_constraints, name[0]))
      {
        if (name[1] == '\0')
  	message_with_line (lineno, "constraint letter '%s' cannot be "
--- 1122,1131 ----
    unsigned int namelen = strlen (name);
    struct constraint_data **iter, **slot, *new;
  
!   /* The 'm' constraint is special here since that constraint letter
!      can be overridden by the back end by defining the
!      TARGET_MEM_CONSTRAINT macro.  */
!   if (strchr (indep_constraints, name[0]) && name[0] != 'm')
      {
        if (name[1] == '\0')
  	message_with_line (lineno, "constraint letter '%s' cannot be "
Index: gcc/doc/md.texi
===================================================================
*** gcc/doc/md.texi.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/doc/md.texi	2008-03-20 14:55:43.000000000 +0100
*************** number of constraints and modifiers.
*** 1085,1090 ****
--- 1085,1092 ----
  @item @samp{m}
  A memory operand is allowed, with any kind of address that the machine
  supports in general.
+ Note that the letter used for the general memory constraint can be
+ re-defined by a back end using the @code{TARGET_MEM_CONSTRAINT} macro.
  
  @cindex offsettable address
  @cindex @samp{o} in constraint
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi.orig	2008-03-20 14:55:11.000000000 +0100
--- gcc/doc/tm.texi	2008-03-20 14:55:43.000000000 +0100
*************** into the @code{symbol_ref}, and then che
*** 5297,5302 ****
--- 5297,5313 ----
  Format}.
  @end defmac
  
+ @defmac TARGET_MEM_CONSTRAINT
+ A single character to be used instead of the default @code{'m'}
+ character for general memory addresses.  This defines the constraint
+ letter which matches the memory addresses accepted by
+ @code{GO_IF_LEGITIMATE_ADDRESS_P}.  Define this macro if you want to
+ support new address formats in your back end without changing the
+ semantics of the @code{'m'} constraint.  This is necessary in order to
+ preserve functionality of inline assembly constructs using the
+ @code{'m'} constraint.
+ @end defmac
+ 
  @defmac FIND_BASE_TERM (@var{x})
  A C expression to determine the base term of address @var{x}.
  This macro is used in only one place: `find_base_term' in alias.c.


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