diff mbox

[4/8] Remove old macros and make lookup_constraint explicit

Message ID 87bnu79h58.fsf@talisman.default
State New
Headers show

Commit Message

Richard Sandiford June 5, 2014, 9:32 p.m. UTC
Now that all extra constraints are defined in .md files, there's no real
need for the old REG_CLASS_FROM_CONSTRAINT-style macros.  The macros also
seem dangerous performance-wise, since each one contains an embedded call to
lookup_constraint.  This means that code like:

		    if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS)
		      {
			if (EXTRA_MEMORY_CONSTRAINT (c, p))
			  ... EXTRA_CONSTRAINT_STR ...
			if (EXTRA_ADDRESS_CONSTRAINT (c, p))
			  ... EXTRA_CONSTRAINT_STR ...
			... EXTRA_CONSTRAINT_STR ...
		      }
		    ...REG_CLASS_FROM_CONSTRAINT...

looks up the same constraint several times.

This patch replaces all uses of:

    REG_CLASS_FROM_CONSTRAINT
    REG_CLASS_FOR_CONSTRAINT
    EXTRA_CONSTRAINT_STR
    EXTRA_MEMORY_CONSTRAINT
    EXTRA_ADDRESS_CONSTRAINT

with separate calls to lookup_constraint and the underlying query function.
It poisons the old macros as a way of protecting against accidental use
(e.g. in #ifdef EXTRA_CONSTRAINT_STR blocks).

Several places want to handle each specific type of constraint in a
different way, so I added a convenience function for classifying constraints
into a type enum.  This also makes the range checks more efficient.
I've treated CONSTRAINT__UNKNOWN as a register constraint (the first type)
since that avoids one more range check and means that each consumer doesn't
have to handle non-constraints specially.  The range check in
reg_class_for_constraint already ensures that the CONSTRAINT__UNKNOWN->
NO_REGS mapping is inline.

Richard


gcc/
	* system.h (REG_CLASS_FROM_CONSTRAINT): Poison.
	(REG_CLASS_FOR_CONSTRAINT, EXTRA_CONSTRAINT_STR): Likewise.
	(EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Likewise.
	* genpreds.c (print_type_tree): New function.
	(write_tm_preds_h): Remove REG_CLASS_FROM_CONSTRAINT,
	REG_CLASS_FOR_CONSTRAINT, EXTRA_MEMORY_CONSTRAINT,
	EXTRA_ADDRESS_CONSTRAINT and EXTRA_CONSTRAINT_STR.
	Write out enum constraint_type and get_constraint_type.
	* lra-constraints.c (satisfies_memory_constraint_p): Take a
	constraint_num rather than a constraint string.
	(satisfies_address_constraint_p): Likewise.
	(reg_class_from_constraints): Avoid old constraint macros.
	(process_alt_operands, process_address_1): Likewise.
	(curr_insn_transform): Likewise.
	* ira-costs.c (record_reg_classes): Likewise.
	(record_operand_costs): Likewise.
	* ira-lives.c (single_reg_class): Likewise.
	(ira_implicitly_set_insn_hard_regs): Likewise.
	* ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise.
	* postreload.c (reload_cse_simplify_operands): Likewise.
	* recog.c (asm_operand_ok, preprocess_constraints): Likewise.
	(constrain_operands, peep2_find_free_register): Likewise.
	* reload.c (push_secondary_reload, scratch_reload_class): Likewise.
	(find_reloads, alternative_allows_const_pool_ref): Likewise.
	* reload1.c (maybe_fix_stack_asms): Likewise.
	* stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
	* targhooks.c (default_secondary_reload): Likewise.
	* config/m32c/m32c.c (m32c_matches_constraint_p): Avoid reference
	to EXTRA_CONSTRAINT_STR.
	* config/sparc/constraints.md (U): Likewise REG_CLASS_FROM_CONSTRAINT.

Comments

Jeff Law June 10, 2014, 8:53 p.m. UTC | #1
On 06/05/14 15:32, Richard Sandiford wrote:
> Now that all extra constraints are defined in .md files, there's no real
> need for the old REG_CLASS_FROM_CONSTRAINT-style macros.  The macros also
> seem dangerous performance-wise, since each one contains an embedded call to
> lookup_constraint.  This means that code like:
>
> 		    if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS)
> 		      {
> 			if (EXTRA_MEMORY_CONSTRAINT (c, p))
> 			  ... EXTRA_CONSTRAINT_STR ...
> 			if (EXTRA_ADDRESS_CONSTRAINT (c, p))
> 			  ... EXTRA_CONSTRAINT_STR ...
> 			... EXTRA_CONSTRAINT_STR ...
> 		      }
> 		    ...REG_CLASS_FROM_CONSTRAINT...
>
> looks up the same constraint several times.
>
> This patch replaces all uses of:
>
>      REG_CLASS_FROM_CONSTRAINT
>      REG_CLASS_FOR_CONSTRAINT
>      EXTRA_CONSTRAINT_STR
>      EXTRA_MEMORY_CONSTRAINT
>      EXTRA_ADDRESS_CONSTRAINT
>
> with separate calls to lookup_constraint and the underlying query function.
> It poisons the old macros as a way of protecting against accidental use
> (e.g. in #ifdef EXTRA_CONSTRAINT_STR blocks).
>
> Several places want to handle each specific type of constraint in a
> different way, so I added a convenience function for classifying constraints
> into a type enum.  This also makes the range checks more efficient.
> I've treated CONSTRAINT__UNKNOWN as a register constraint (the first type)
> since that avoids one more range check and means that each consumer doesn't
> have to handle non-constraints specially.  The range check in
> reg_class_for_constraint already ensures that the CONSTRAINT__UNKNOWN->
> NO_REGS mapping is inline.
>
> Richard
>
>
> gcc/
> 	* system.h (REG_CLASS_FROM_CONSTRAINT): Poison.
> 	(REG_CLASS_FOR_CONSTRAINT, EXTRA_CONSTRAINT_STR): Likewise.
> 	(EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Likewise.
> 	* genpreds.c (print_type_tree): New function.
> 	(write_tm_preds_h): Remove REG_CLASS_FROM_CONSTRAINT,
> 	REG_CLASS_FOR_CONSTRAINT, EXTRA_MEMORY_CONSTRAINT,
> 	EXTRA_ADDRESS_CONSTRAINT and EXTRA_CONSTRAINT_STR.
> 	Write out enum constraint_type and get_constraint_type.
> 	* lra-constraints.c (satisfies_memory_constraint_p): Take a
> 	constraint_num rather than a constraint string.
> 	(satisfies_address_constraint_p): Likewise.
> 	(reg_class_from_constraints): Avoid old constraint macros.
> 	(process_alt_operands, process_address_1): Likewise.
> 	(curr_insn_transform): Likewise.
> 	* ira-costs.c (record_reg_classes): Likewise.
> 	(record_operand_costs): Likewise.
> 	* ira-lives.c (single_reg_class): Likewise.
> 	(ira_implicitly_set_insn_hard_regs): Likewise.
> 	* ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise.
> 	* postreload.c (reload_cse_simplify_operands): Likewise.
> 	* recog.c (asm_operand_ok, preprocess_constraints): Likewise.
> 	(constrain_operands, peep2_find_free_register): Likewise.
> 	* reload.c (push_secondary_reload, scratch_reload_class): Likewise.
> 	(find_reloads, alternative_allows_const_pool_ref): Likewise.
> 	* reload1.c (maybe_fix_stack_asms): Likewise.
> 	* stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
> 	* targhooks.c (default_secondary_reload): Likewise.
> 	* config/m32c/m32c.c (m32c_matches_constraint_p): Avoid reference
> 	to EXTRA_CONSTRAINT_STR.
> 	* config/sparc/constraints.md (U): Likewise REG_CLASS_FROM_CONSTRAINT.
Given the level of testing you've done, I only spot checked a few places 
after concluding the general direction you were going makes sense.  I 
don't expect any fallout, but I'm confident you'll deal with it if it 
happens.

Thanks.  OK for the trunk,

Jeff
diff mbox

Patch

Index: gcc/system.h
===================================================================
--- gcc/system.h	2014-06-05 21:06:52.721540056 +0100
+++ gcc/system.h	2014-06-05 21:45:00.219282847 +0100
@@ -930,7 +930,10 @@  #define realloc xrealloc
         GO_IF_MODE_DEPENDENT_ADDRESS DELAY_SLOTS_FOR_EPILOGUE              \
         ELIGIBLE_FOR_EPILOGUE_DELAY TARGET_C99_FUNCTIONS TARGET_HAS_SINCOS \
 	REG_CLASS_FROM_LETTER CONST_OK_FOR_LETTER_P			   \
-	CONST_DOUBLE_OK_FOR_LETTER_P EXTRA_CONSTRAINT
+	CONST_DOUBLE_OK_FOR_LETTER_P EXTRA_CONSTRAINT			   \
+	REG_CLASS_FROM_CONSTRAINT REG_CLASS_FOR_CONSTRAINT		   \
+	EXTRA_CONSTRAINT_STR EXTRA_MEMORY_CONSTRAINT			   \
+	EXTRA_ADDRESS_CONSTRAINT
 
 /* Hooks that are no longer used.  */
  #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE	\
Index: gcc/genpreds.c
===================================================================
--- gcc/genpreds.c	2014-06-05 21:45:00.187282566 +0100
+++ gcc/genpreds.c	2014-06-05 21:45:00.211282777 +0100
@@ -1232,6 +1232,33 @@  write_range_function (const char *name,
 	    "}\n\n", name);
 }
 
+/* VEC is a list of key/value pairs, with the keys being lower bounds
+   of a range.  Output a decision tree that handles the keys covered by
+   [VEC[START], VEC[END]), returning FALLBACK for keys lower then VEC[START]'s.
+   INDENT is the number of spaces to indent the code.  */
+static void
+print_type_tree (const vec <std::pair <unsigned int, const char *> > &vec,
+		 unsigned int start, unsigned int end, const char *fallback,
+		 unsigned int indent)
+{
+  while (start < end)
+    {
+      unsigned int mid = (start + end) / 2;
+      printf ("%*sif (c >= CONSTRAINT_%s)\n",
+	      indent, "", enum_order[vec[mid].first]->c_name);
+      if (mid + 1 == end)
+	print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 2);
+      else
+	{
+	  printf ("%*s{\n", indent + 2, "");
+	  print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 4);
+	  printf ("%*s}\n", indent + 2, "");
+	}
+      end = mid;
+    }
+  printf ("%*sreturn %s;\n", indent, "", fallback);
+}
+
 /* Write tm-preds.h.  Unfortunately, it is impossible to forward-declare
    an enumeration in portable C, so we have to condition all these
    prototypes on HAVE_MACHINE_MODES.  */
@@ -1321,21 +1348,13 @@  #define GCC_TM_PREDS_H\n\
 	      "  if (insn_extra_register_constraint (c))\n"
 	      "    return reg_class_for_constraint_1 (c);\n"
 	      "  return NO_REGS;\n"
-	      "}\n"
-	      "\n"
-	      "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n"
-	      "    reg_class_for_constraint (lookup_constraint (s_))\n"
-	      "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n"
-	      "    reg_class_for_constraint (x_)\n");
+	      "}\n");
       else
 	puts ("static inline enum reg_class\n"
 	      "reg_class_for_constraint (enum constraint_num)\n"
 	      "{\n"
 	      "  return NO_REGS;\n"
-	      "}\n\n"
-	      "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS\n"
-	      "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n"
-	      "    NO_REGS\n");
+	      "}\n");
       if (have_const_int_constraints)
 	puts ("extern bool insn_const_int_ok_for_constraint "
 	      "(HOST_WIDE_INT, enum constraint_num);\n"
@@ -1347,19 +1366,27 @@  #define GCC_TM_PREDS_H\n\
 	      "    constraint_satisfied_p (v_, lookup_constraint (s_))\n");
       else
 	puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) 0\n");
-      if (have_extra_constraints)
-	puts ("#define EXTRA_CONSTRAINT_STR(v_,c_,s_) \\\n"
-	      "    constraint_satisfied_p (v_, lookup_constraint (s_))\n");
-      if (have_memory_constraints)
-	puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) "
-	      "insn_extra_memory_constraint (lookup_constraint (s_))\n");
-      else
-	puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) false\n");
-      if (have_address_constraints)
-	puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) "
-	      "insn_extra_address_constraint (lookup_constraint (s_))\n");
-      else
-	puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) false\n");
+
+      puts ("enum constraint_type\n"
+	    "{\n"
+	    "  CT_REGISTER,\n"
+	    "  CT_MEMORY,\n"
+	    "  CT_ADDRESS,\n"
+	    "  CT_FIXED_FORM\n"
+	    "};\n"
+	    "\n"
+	    "static inline enum constraint_type\n"
+	    "get_constraint_type (enum constraint_num c)\n"
+	    "{");
+      auto_vec <std::pair <unsigned int, const char *>, 3> values;
+      if (memory_start != memory_end)
+	values.safe_push (std::make_pair (memory_start, "CT_MEMORY"));
+      if (address_start != address_end)
+	values.safe_push (std::make_pair (address_start, "CT_ADDRESS"));
+      if (address_end != num_constraints)
+	values.safe_push (std::make_pair (address_end, "CT_FIXED_FORM"));
+      print_type_tree (values, 0, values.length (), "CT_REGISTER", 2);
+      puts ("}");
     }
 
   puts ("#endif /* tm-preds.h */");
Index: gcc/lra-constraints.c
===================================================================
--- gcc/lra-constraints.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/lra-constraints.c	2014-06-05 21:46:37.913140623 +0100
@@ -394,40 +394,38 @@  valid_address_p (struct address_info *ad
   return valid_address_p (ad->mode, *ad->outer, ad->as);
 }
 
-#ifdef EXTRA_CONSTRAINT_STR
 /* Return true if the eliminated form of memory reference OP satisfies
    extra memory constraint CONSTRAINT.  */
 static bool
-satisfies_memory_constraint_p (rtx op, const char *constraint)
+satisfies_memory_constraint_p (rtx op, enum constraint_num constraint)
 {
   struct address_info ad;
 
   decompose_mem_address (&ad, op);
   address_eliminator eliminator (&ad);
-  return EXTRA_CONSTRAINT_STR (op, *constraint, constraint);
+  return constraint_satisfied_p (op, constraint);
 }
 
 /* Return true if the eliminated form of address AD satisfies extra
    address constraint CONSTRAINT.  */
 static bool
 satisfies_address_constraint_p (struct address_info *ad,
-				const char *constraint)
+				enum constraint_num constraint)
 {
   address_eliminator eliminator (ad);
-  return EXTRA_CONSTRAINT_STR (*ad->outer, *constraint, constraint);
+  return constraint_satisfied_p (*ad->outer, constraint);
 }
 
 /* Return true if the eliminated form of address OP satisfies extra
    address constraint CONSTRAINT.  */
 static bool
-satisfies_address_constraint_p (rtx op, const char *constraint)
+satisfies_address_constraint_p (rtx op, enum constraint_num constraint)
 {
   struct address_info ad;
 
   decompose_lea_address (&ad, &op);
   return satisfies_address_constraint_p (&ad, constraint);
 }
-#endif
 
 /* Initiate equivalences for LRA.  As we keep original equivalences
    before any elimination, we need to make copies otherwise any change
@@ -982,21 +980,20 @@  reg_class_from_constraints (const char *
 	break;
 
       default:
-	if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS)
+	enum constraint_num cn = lookup_constraint (p);
+	enum reg_class cl = reg_class_for_constraint (cn);
+	if (cl == NO_REGS)
 	  {
-#ifdef EXTRA_CONSTRAINT_STR
-	    if (EXTRA_ADDRESS_CONSTRAINT (c, p))
+	    if (insn_extra_address_constraint (cn))
 	      op_class
 		= (reg_class_subunion
 		   [op_class][base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
 					      ADDRESS, SCRATCH)]);
-#endif
 	    break;
 	  }
 
-	op_class
-	  = reg_class_subunion[op_class][REG_CLASS_FROM_CONSTRAINT (c, p)];
-	break;
+	op_class = reg_class_subunion[op_class][cl];
+ 	break;
       }
   while ((p += len), c);
   return op_class;
@@ -1712,6 +1709,7 @@  process_alt_operands (int only_alternati
 	  bool this_alternative_offmemok;
 	  bool scratch_p;
 	  enum machine_mode mode;
+	  enum constraint_num cn;
 
 	  opalt_num = nalt * n_operands + nop;
 	  if (curr_static_id->operand_alternative[opalt_num].anything_ok)
@@ -2030,76 +2028,55 @@  process_alt_operands (int only_alternati
 		  /* Drop through into 'r' case.  */
 
 		case 'r':
-		  this_alternative
-		    = reg_class_subunion[this_alternative][GENERAL_REGS];
-		  IOR_HARD_REG_SET (this_alternative_set,
-				    reg_class_contents[GENERAL_REGS]);
-		  if (costly_p)
-		    {
-		      this_costly_alternative
-			= (reg_class_subunion
-			   [this_costly_alternative][GENERAL_REGS]);
-		      IOR_HARD_REG_SET (this_costly_alternative_set,
-					reg_class_contents[GENERAL_REGS]);
-		    }
+		  cl = GENERAL_REGS;
 		  goto reg;
 
 		default:
-		  if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS)
+		  cn = lookup_constraint (p);
+		  switch (get_constraint_type (cn))
 		    {
-#ifdef EXTRA_CONSTRAINT_STR
-		      if (EXTRA_MEMORY_CONSTRAINT (c, p))
-			{
-			  if (MEM_P (op)
-			      && satisfies_memory_constraint_p (op, p))
-			    win = true;
-			  else if (spilled_pseudo_p (op))
-			    win = true;
-
-			  /* If we didn't already win, we can reload
-			     constants via force_const_mem or put the
-			     pseudo value into memory, or make other
-			     memory by reloading the address like for
-			     'o'.  */
-			  if (CONST_POOL_OK_P (mode, op)
-			      || MEM_P (op) || REG_P (op))
-			    badop = false;
-			  constmemok = true;
-			  offmemok = true;
-			  break;
-			}
-		      if (EXTRA_ADDRESS_CONSTRAINT (c, p))
-			{
-			  if (satisfies_address_constraint_p (op, p))
-			    win = true;
+		    case CT_REGISTER:
+		      cl = reg_class_for_constraint (cn);
+		      if (cl != NO_REGS)
+			goto reg;
+		      break;
 
-			  /* If we didn't already win, we can reload
-			     the address into a base register.	*/
-			  cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
-					       ADDRESS, SCRATCH);
-			  this_alternative
-			    = reg_class_subunion[this_alternative][cl];
-			  IOR_HARD_REG_SET (this_alternative_set,
-					    reg_class_contents[cl]);
-			  if (costly_p)
-			    {
-			      this_costly_alternative
-				= (reg_class_subunion
-				   [this_costly_alternative][cl]);
-			      IOR_HARD_REG_SET (this_costly_alternative_set,
-						reg_class_contents[cl]);
-			    }
-			  badop = false;
-			  break;
-			}
+		    case CT_MEMORY:
+		      if (MEM_P (op)
+			  && satisfies_memory_constraint_p (op, cn))
+			win = true;
+		      else if (spilled_pseudo_p (op))
+			win = true;
 
-		      if (EXTRA_CONSTRAINT_STR (op, c, p))
+		      /* If we didn't already win, we can reload constants
+			 via force_const_mem or put the pseudo value into
+			 memory, or make other memory by reloading the
+			 address like for 'o'.  */
+		      if (CONST_POOL_OK_P (mode, op)
+			  || MEM_P (op) || REG_P (op))
+			badop = false;
+		      constmemok = true;
+		      offmemok = true;
+		      break;
+
+		    case CT_ADDRESS:
+		      /* If we didn't already win, we can reload the address
+			 into a base register.  */
+		      if (satisfies_address_constraint_p (op, cn))
+			win = true;
+		      cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
+					   ADDRESS, SCRATCH);
+		      badop = false;
+		      goto reg;
+
+		    case CT_FIXED_FORM:
+		      if (constraint_satisfied_p (op, cn))
 			win = true;
-#endif
 		      break;
 		    }
+		  break;
 
-		  cl = REG_CLASS_FROM_CONSTRAINT (c, p);
+		reg:
 		  this_alternative = reg_class_subunion[this_alternative][cl];
 		  IOR_HARD_REG_SET (this_alternative_set,
 				    reg_class_contents[cl]);
@@ -2110,7 +2087,6 @@  process_alt_operands (int only_alternati
 		      IOR_HARD_REG_SET (this_costly_alternative_set,
 					reg_class_contents[cl]);
 		    }
-		reg:
 		  if (mode == BLKmode)
 		    break;
 		  winreg = true;
@@ -2856,10 +2832,11 @@  process_address_1 (int nop, rtx *before,
   rtx new_reg;
   rtx op = *curr_id->operand_loc[nop];
   const char *constraint = curr_static_id->operand[nop].constraint;
+  enum constraint_num cn = lookup_constraint (constraint);
   bool change_p;
 
   if (constraint[0] == 'p'
-      || EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint))
+      || insn_extra_address_constraint (cn))
     decompose_lea_address (&ad, curr_id->operand_loc[nop]);
   else if (MEM_P (op))
     decompose_mem_address (&ad, op);
@@ -2888,14 +2865,12 @@  process_address_1 (int nop, rtx *before,
       && process_addr_reg (ad.index_term, before, NULL, INDEX_REG_CLASS))
     change_p = true;
 
-#ifdef EXTRA_CONSTRAINT_STR
-  /* Target hooks sometimes reject extra constraint addresses -- use
-     EXTRA_CONSTRAINT_STR for the validation.  */
+  /* Target hooks sometimes don't treat extra-constraint addresses as
+     legitimate address_operands, so handle them specially.  */
   if (constraint[0] != 'p'
-      && EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint)
-      && satisfies_address_constraint_p (&ad, constraint))
+      && insn_extra_address_constraint (cn)
+      && satisfies_address_constraint_p (&ad, cn))
     return change_p;
-#endif
 
   /* There are three cases where the shape of *AD.INNER may now be invalid:
 
@@ -3610,11 +3585,10 @@  curr_insn_transform (void)
 	      {
 		if (c == TARGET_MEM_CONSTRAINT || c == 'o')
 		  break;
-#ifdef EXTRA_CONSTRAINT_STR
-		if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
-		    && satisfies_memory_constraint_p (tem, constraint))
+		enum constraint_num cn = lookup_constraint (constraint);
+		if (insn_extra_memory_constraint (cn)
+		    && satisfies_memory_constraint_p (tem, cn))
 		  break;
-#endif
 	      }
 	    if (c == '\0' || c == ',' || c == '#')
 	      continue;
Index: gcc/ira-costs.c
===================================================================
--- gcc/ira-costs.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/ira-costs.c	2014-06-05 21:45:00.208282750 +0100
@@ -753,25 +753,28 @@  record_reg_classes (int n_alts, int n_op
 		  break;
 
 		default:
-		  if (REG_CLASS_FROM_CONSTRAINT (c, p) != NO_REGS)
-		    classes[i] = ira_reg_class_subunion[classes[i]]
-		                 [REG_CLASS_FROM_CONSTRAINT (c, p)];
-#ifdef EXTRA_CONSTRAINT_STR
-		  else if (EXTRA_CONSTRAINT_STR (op, c, p))
-		    win = 1;
-
-		  if (EXTRA_MEMORY_CONSTRAINT (c, p))
+		  enum constraint_num cn = lookup_constraint (p);
+		  enum reg_class cl;
+		  switch (get_constraint_type (cn))
 		    {
+		    case CT_REGISTER:
+		      cl = reg_class_for_constraint (cn);
+		      if (cl != NO_REGS)
+			classes[i] = ira_reg_class_subunion[classes[i]][cl];
+		      break;
+
+		    case CT_MEMORY:
 		      /* Every MEM can be reloaded to fit.  */
 		      insn_allows_mem[i] = allows_mem[i] = 1;
 		      if (MEM_P (op))
 			win = 1;
-		    }
-		  if (EXTRA_ADDRESS_CONSTRAINT (c, p))
-		    {
+		      break;
+
+		    case CT_ADDRESS:
 		      /* Every address can be reloaded to fit.  */
 		      allows_addr = 1;
-		      if (address_operand (op, GET_MODE (op)))
+		      if (address_operand (op, GET_MODE (op))
+			  || constraint_satisfied_p (op, cn))
 			win = 1;
 		      /* We know this operand is an address, so we
 			 want it to be allocated to a hard register
@@ -781,8 +784,13 @@  record_reg_classes (int n_alts, int n_op
 			= ira_reg_class_subunion[classes[i]]
 			  [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
 					   ADDRESS, SCRATCH)];
+		      break;
+
+		    case CT_FIXED_FORM:
+		      if (constraint_satisfied_p (op, cn))
+			win = 1;
+		      break;
 		    }
-#endif
 		  break;
 		}
 	      p += CONSTRAINT_LEN (c, p);
@@ -1275,8 +1283,8 @@  record_operand_costs (rtx insn, enum reg
 			     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]))
+	       || (insn_extra_address_constraint
+		   (lookup_constraint (constraints[i]))))
 	record_address_regs (VOIDmode, ADDR_SPACE_GENERIC,
 			     recog_data.operand[i], 0, ADDRESS, SCRATCH,
 			     frequency * 2);
Index: gcc/ira-lives.c
===================================================================
--- gcc/ira-lives.c	2014-06-05 21:45:00.132282083 +0100
+++ gcc/ira-lives.c	2014-06-05 21:45:00.212282786 +0100
@@ -759,6 +759,7 @@  single_reg_class (const char *constraint
 {
   int c;
   enum reg_class cl, next_cl;
+  enum constraint_num cn;
 
   cl = NO_REGS;
   alternative_mask enabled = recog_data.enabled_alternatives;
@@ -849,20 +850,19 @@  single_reg_class (const char *constraint
 	case 'A': case 'B': case 'C': case 'D':
 	case 'Q': case 'R': case 'S': case 'T': case 'U':
 	case 'W': case 'Y': case 'Z':
-#ifdef EXTRA_CONSTRAINT_STR
 	  /* ??? Is this the best way to handle memory constraints?  */
-	  if (EXTRA_MEMORY_CONSTRAINT (c, constraints)
-	      || EXTRA_ADDRESS_CONSTRAINT (c, constraints))
+	  cn = lookup_constraint (constraints);
+	  if (insn_extra_memory_constraint (cn)
+	      || insn_extra_address_constraint (cn))
 	    return NO_REGS;
-	  if (EXTRA_CONSTRAINT_STR (op, c, constraints)
+	  if (constraint_satisfied_p (op, cn)
 	      || (equiv_const != NULL_RTX
 		  && CONSTANT_P (equiv_const)
-		  && EXTRA_CONSTRAINT_STR (equiv_const, c, constraints)))
+		  && constraint_satisfied_p (equiv_const, cn)))
 	    return NO_REGS;
-#endif
 	  next_cl = (c == 'r'
 		     ? GENERAL_REGS
-		     : REG_CLASS_FROM_CONSTRAINT (c, constraints));
+		     : reg_class_for_constraint (cn));
 	  if (next_cl == NO_REGS)
 	    break;
 	  if (cl == NO_REGS
@@ -950,7 +950,7 @@  ira_implicitly_set_insn_hard_regs (HARD_
 		case 'W': case 'Y': case 'Z':
 		  cl = (c == 'r'
 			? GENERAL_REGS
-			: REG_CLASS_FROM_CONSTRAINT (c, p));
+			: reg_class_for_constraint (lookup_constraint (p)));
 		  if (cl != NO_REGS)
 		    {
 		      /* There is no register pressure problem if all of the
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/ira.c	2014-06-05 21:45:00.204282715 +0100
@@ -1922,24 +1922,29 @@  ira_setup_alts (rtx insn, HARD_REG_SET &
 		    break;
 		    
 		  case 'o':
+		  case 'r':
 		    goto op_success;
 		    break;
 		    
 		  default:
 		    {
-		      enum reg_class cl;
-		      
-		      cl = (c == 'r' ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p));
-		      if (cl != NO_REGS)
-			goto op_success;
-#ifdef EXTRA_CONSTRAINT_STR
-		      else if (EXTRA_CONSTRAINT_STR (op, c, p))
-			goto op_success;
-		      else if (EXTRA_MEMORY_CONSTRAINT (c, p))
-			goto op_success;
-		      else if (EXTRA_ADDRESS_CONSTRAINT (c, p))
-			goto op_success;
-#endif
+		      enum constraint_num cn = lookup_constraint (p);
+		      switch (get_constraint_type (cn))
+			{
+			case CT_REGISTER:
+			  if (reg_class_for_constraint (cn) != NO_REGS)
+			    goto op_success;
+			  break;
+
+			case CT_ADDRESS:
+			case CT_MEMORY:
+			  goto op_success;
+
+			case CT_FIXED_FORM:
+			  if (constraint_satisfied_p (op, cn))
+			    goto op_success;
+			  break;
+			}
 		      break;
 		    }
 		  }
@@ -1972,9 +1977,6 @@  ira_get_dup_out_num (int op_num, HARD_RE
   int curr_alt, c, original, dup;
   bool ignore_p, use_commut_op_p;
   const char *str;
-#ifdef EXTRA_CONSTRAINT_STR
-  rtx op;
-#endif
 
   if (op_num < 0 || recog_data.n_alternatives == 0)
     return -1;
@@ -1985,9 +1987,7 @@  ira_get_dup_out_num (int op_num, HARD_RE
   use_commut_op_p = false;
   for (;;)
     {
-#ifdef EXTRA_CONSTRAINT_STR
-      op = recog_data.operand[op_num];
-#endif
+      rtx op = recog_data.operand[op_num];
       
       for (curr_alt = 0, ignore_p = !TEST_HARD_REG_BIT (alts, curr_alt),
 	   original = -1;;)
@@ -2010,6 +2010,9 @@  ira_get_dup_out_num (int op_num, HARD_RE
 	      case 'g':
 		goto fail;
 	      case 'r':
+		if (!targetm.class_likely_spilled_p (GENERAL_REGS))
+		  goto fail;
+		break;
 	      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
 	      case 'h': case 'j': case 'k': case 'l':
 	      case 'q': case 't': case 'u':
@@ -2018,19 +2021,13 @@  ira_get_dup_out_num (int op_num, HARD_RE
 	      case 'Q': case 'R': case 'S': case 'T': case 'U':
 	      case 'W': case 'Y': case 'Z':
 		{
-		  enum reg_class cl;
-		  
-		  cl = (c == 'r'
-			? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, str));
-		  if (cl != NO_REGS)
-		    {
-		      if (! targetm.class_likely_spilled_p (cl))
-			goto fail;
-		    }
-#ifdef EXTRA_CONSTRAINT_STR
-		  else if (EXTRA_CONSTRAINT_STR (op, c, str))
+		  enum constraint_num cn = lookup_constraint (str);
+		  enum reg_class cl = reg_class_for_constraint (cn);
+		  if (cl != NO_REGS
+		      && !targetm.class_likely_spilled_p (cl))
+		    goto fail;
+		  if (constraint_satisfied_p (op, cn))
 		    goto fail;
-#endif
 		  break;
 		}
 		
Index: gcc/postreload.c
===================================================================
--- gcc/postreload.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/postreload.c	2014-06-05 21:45:00.220282856 +0100
@@ -574,8 +574,8 @@  reload_cse_simplify_operands (rtx insn,
 		default:
 		  rclass
 		    = (reg_class_subunion
-		       [(int) rclass]
-		       [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
+		       [rclass]
+		       [reg_class_for_constraint (lookup_constraint (p))]);
 		  break;
 
 		case ',': case '\0':
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/recog.c	2014-06-05 21:45:00.209282759 +0100
@@ -1729,6 +1729,7 @@  asm_operand_ok (rtx op, const char *cons
 
   while (*constraint)
     {
+      enum constraint_num cn;
       char c = *constraint;
       int len;
       switch (c)
@@ -1902,27 +1903,37 @@  asm_operand_ok (rtx op, const char *cons
 	    result = 1;
 	  break;
 
+	case 'r':
+	reg:
+	  if (!result
+	      && GET_MODE (op) != BLKmode
+	      && register_operand (op, VOIDmode))
+	    result = 1;
+	  break;
+
 	default:
-	  /* For all other letters, we first check for a register class,
-	     otherwise it is an EXTRA_CONSTRAINT.  */
-	  if (REG_CLASS_FROM_CONSTRAINT (c, constraint) != NO_REGS)
+	  cn = lookup_constraint (constraint);
+	  switch (get_constraint_type (cn))
 	    {
-	    case 'r':
-	      if (GET_MODE (op) == BLKmode)
-		break;
-	      if (register_operand (op, VOIDmode))
-		result = 1;
+	    case CT_REGISTER:
+	      if (reg_class_for_constraint (cn) != NO_REGS)
+		goto reg;
+	      break;
+
+	    case CT_MEMORY:
+	      /* Every memory operand can be reloaded to fit.  */
+	      result = result || memory_operand (op, VOIDmode);
+	      break;
+
+	    case CT_ADDRESS:
+	      /* Every address operand can be reloaded to fit.  */
+	      result = result || address_operand (op, VOIDmode);
+	      break;
+
+	    case CT_FIXED_FORM:
+	      result = result || constraint_satisfied_p (op, cn);
+	      break;
 	    }
-#ifdef EXTRA_CONSTRAINT_STR
-	  else if (EXTRA_MEMORY_CONSTRAINT (c, constraint))
-	    /* Every memory operand can be reloaded to fit.  */
-	    result = result || memory_operand (op, VOIDmode);
-	  else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint))
-	    /* Every address operand can be reloaded to fit.  */
-	    result = result || address_operand (op, VOIDmode);
-	  else if (EXTRA_CONSTRAINT_STR (op, c, constraint))
-	    result = 1;
-#endif
 	  break;
 	}
       len = CONSTRAINT_LEN (c, constraint);
@@ -2434,13 +2445,21 @@  preprocess_constraints (int n_operands,
 		  break;
 
 		default:
-		  if (EXTRA_MEMORY_CONSTRAINT (c, p))
+		  enum constraint_num cn = lookup_constraint (p);
+		  enum reg_class cl;
+		  switch (get_constraint_type (cn))
 		    {
+		    case CT_REGISTER:
+		      cl = reg_class_for_constraint (cn);
+		      if (cl != NO_REGS)
+			op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
+		      break;
+
+		    case CT_MEMORY:
 		      op_alt[i].memory_ok = 1;
 		      break;
-		    }
-		  if (EXTRA_ADDRESS_CONSTRAINT (c, p))
-		    {
+
+		    case CT_ADDRESS:
 		      op_alt[i].is_address = 1;
 		      op_alt[i].cl
 			= (reg_class_subunion
@@ -2448,12 +2467,10 @@  preprocess_constraints (int n_operands,
 			   [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
 						  ADDRESS, SCRATCH)]);
 		      break;
-		    }
 
-		  op_alt[i].cl
-		    = (reg_class_subunion
-		       [(int) op_alt[i].cl]
-		       [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
+		    case CT_FIXED_FORM:
+		      break;
+		    }
 		  break;
 		}
 	      p += CONSTRAINT_LEN (c, p);
@@ -2846,9 +2863,12 @@  constrain_operands (int strict)
 	      default:
 		{
 		  enum reg_class cl;
+		  enum constraint_num cn = (c == 'r'
+					    ? CONSTRAINT__UNKNOWN
+					    : lookup_constraint (p));
 
 		  cl = (c == 'r'
-			   ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p));
+			? GENERAL_REGS : reg_class_for_constraint (cn));
 		  if (cl != NO_REGS)
 		    {
 		      if (strict < 0
@@ -2860,11 +2880,11 @@  constrain_operands (int strict)
 			      && reg_fits_class_p (op, cl, offset, mode)))
 		        win = 1;
 		    }
-#ifdef EXTRA_CONSTRAINT_STR
-		  else if (EXTRA_CONSTRAINT_STR (op, c, p))
+
+		  else if (constraint_satisfied_p (op, cn))
 		    win = 1;
 
-		  else if (EXTRA_MEMORY_CONSTRAINT (c, p)
+		  else if (insn_extra_memory_constraint (cn)
 			   /* Every memory operand can be reloaded to fit.  */
 			   && ((strict < 0 && MEM_P (op))
 			       /* Before reload, accept what reload can turn
@@ -2874,7 +2894,7 @@  constrain_operands (int strict)
 			       || (reload_in_progress && REG_P (op)
 				   && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
 		    win = 1;
-		  else if (EXTRA_ADDRESS_CONSTRAINT (c, p)
+		  else if (insn_extra_address_constraint (cn)
 			   /* Every address operand can be reloaded to fit.  */
 			   && strict < 0)
 		    win = 1;
@@ -2885,10 +2905,9 @@  constrain_operands (int strict)
 			   && REGNO (op) >= FIRST_PSEUDO_REGISTER
 			   && reg_renumber[REGNO (op)] < 0
 			   && reg_equiv_mem (REGNO (op)) != 0
-			   && EXTRA_CONSTRAINT_STR
-			      (reg_equiv_mem (REGNO (op)), c, p))
+			   && constraint_satisfied_p
+			      (reg_equiv_mem (REGNO (op)), cn))
 		    win = 1;
-#endif
 		  break;
 		}
 	      }
@@ -3283,7 +3302,7 @@  peep2_find_free_register (int from, int
     }
 
   cl = (class_str[0] == 'r' ? GENERAL_REGS
-	   : REG_CLASS_FROM_CONSTRAINT (class_str[0], class_str));
+	: reg_class_for_constraint (lookup_constraint (class_str)));
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
Index: gcc/reload.c
===================================================================
--- gcc/reload.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/reload.c	2014-06-05 21:45:00.214282803 +0100
@@ -401,8 +401,8 @@  push_secondary_reload (int in_p, rtx x,
 	scratch_constraint++;
       letter = *scratch_constraint;
       scratch_class = (letter == 'r' ? GENERAL_REGS
-		       : REG_CLASS_FROM_CONSTRAINT ((unsigned char) letter,
-						   scratch_constraint));
+		       : (reg_class_for_constraint
+			  (lookup_constraint (scratch_constraint))));
 
       rclass = scratch_class;
       mode = insn_data[(int) icode].operand[2].mode;
@@ -560,8 +560,7 @@  scratch_reload_class (enum insn_code ico
   scratch_letter = *scratch_constraint;
   if (scratch_letter == 'r')
     return GENERAL_REGS;
-  rclass = REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter,
-				     scratch_constraint);
+  rclass = reg_class_for_constraint (lookup_constraint (scratch_constraint));
   gcc_assert (rclass != NO_REGS);
   return rclass;
 }
@@ -2852,7 +2851,8 @@  find_reloads (rtx insn, int replace, int
 	/* Ignore things like match_operator operands.  */
 	;
       else if (constraints[i][0] == 'p'
-	       || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i]))
+	       || (insn_extra_address_constraint
+		   (lookup_constraint (constraints[i]))))
 	{
 	  address_operand_reloaded[i]
 	    = find_reloads_address (recog_data.operand_mode[i], (rtx*) 0,
@@ -3094,6 +3094,8 @@  find_reloads (rtx insn, int replace, int
 		 operand.  */
 	      int constmemok = 0;
 	      int earlyclobber = 0;
+	      enum constraint_num cn;
+	      enum reg_class cl;
 
 	      /* If the predicate accepts a unary operator, it means that
 		 we need to reload the operand, but do not do this for
@@ -3489,71 +3491,74 @@  find_reloads (rtx insn, int replace, int
 		    /* Drop through into 'r' case.  */
 
 		  case 'r':
-		    this_alternative[i]
-		      = reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS];
+		    cl = GENERAL_REGS;
 		    goto reg;
 
 		  default:
-		    if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS)
+		    cn = lookup_constraint (p);
+		    switch (get_constraint_type (cn))
 		      {
-#ifdef EXTRA_CONSTRAINT_STR
-			if (EXTRA_MEMORY_CONSTRAINT (c, p))
-			  {
-			    if (force_reload)
-			      break;
-			    if (EXTRA_CONSTRAINT_STR (operand, c, p))
-			      win = 1;
-			    /* If the address was already reloaded,
-			       we win as well.  */
-			    else if (MEM_P (operand)
-				     && address_reloaded[i] == 1)
-			      win = 1;
-			    /* Likewise if the address will be reloaded because
-			       reg_equiv_address is nonzero.  For reg_equiv_mem
-			       we have to check.  */
-			    else if (REG_P (operand)
-				     && REGNO (operand) >= FIRST_PSEUDO_REGISTER
-				     && reg_renumber[REGNO (operand)] < 0
-				     && ((reg_equiv_mem (REGNO (operand)) != 0
-					  && EXTRA_CONSTRAINT_STR (reg_equiv_mem (REGNO (operand)), c, p))
-					 || (reg_equiv_address (REGNO (operand)) != 0)))
-			      win = 1;
-
-			    /* If we didn't already win, we can reload
-			       constants via force_const_mem, and other
-			       MEMs by reloading the address like for 'o'.  */
-			    if (CONST_POOL_OK_P (operand_mode[i], operand)
-				|| MEM_P (operand))
-			      badop = 0;
-			    constmemok = 1;
-			    offmemok = 1;
-			    break;
-			  }
-			if (EXTRA_ADDRESS_CONSTRAINT (c, p))
-			  {
-			    if (EXTRA_CONSTRAINT_STR (operand, c, p))
-			      win = 1;
+		      case CT_REGISTER:
+			cl = reg_class_for_constraint (cn);
+			if (cl != NO_REGS)
+			  goto reg;
+			break;
 
-			    /* 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;
-			  }
+		      case CT_MEMORY:
+			if (force_reload)
+			  break;
+			if (constraint_satisfied_p (operand, cn))
+			  win = 1;
+			/* If the address was already reloaded,
+			   we win as well.  */
+			else if (MEM_P (operand) && address_reloaded[i] == 1)
+			  win = 1;
+			/* Likewise if the address will be reloaded because
+			   reg_equiv_address is nonzero.  For reg_equiv_mem
+			   we have to check.  */
+			else if (REG_P (operand)
+				 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+				 && reg_renumber[REGNO (operand)] < 0
+				 && ((reg_equiv_mem (REGNO (operand)) != 0
+				      && (constraint_satisfied_p
+					  (reg_equiv_mem (REGNO (operand)),
+					   cn)))
+				     || (reg_equiv_address (REGNO (operand))
+					 != 0)))
+			  win = 1;
 
-			if (EXTRA_CONSTRAINT_STR (operand, c, p))
+			/* If we didn't already win, we can reload
+			   constants via force_const_mem, and other
+			   MEMs by reloading the address like for 'o'.  */
+			if (CONST_POOL_OK_P (operand_mode[i], operand)
+			    || MEM_P (operand))
+			  badop = 0;
+			constmemok = 1;
+			offmemok = 1;
+			break;
+
+		      case CT_ADDRESS:
+			if (constraint_satisfied_p (operand, cn))
+			  win = 1;
+
+			/* 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;
+
+		      case CT_FIXED_FORM:
+			if (constraint_satisfied_p (operand, cn))
 			  win = 1;
-#endif
 			break;
 		      }
+		    break;
 
-		    this_alternative[i]
-		      = (reg_class_subunion
-			 [this_alternative[i]]
-			 [(int) REG_CLASS_FROM_CONSTRAINT (c, p)]);
 		  reg:
+		    this_alternative[i]
+		      = reg_class_subunion[this_alternative[i]][cl];
 		    if (GET_MODE (operand) == BLKmode)
 		      break;
 		    winreg = 1;
@@ -4687,11 +4692,10 @@  alternative_allows_const_pool_ref (rtx m
     {
       if (c == TARGET_MEM_CONSTRAINT || c == 'o')
 	return true;
-#ifdef EXTRA_CONSTRAINT_STR
-      if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
-	  && (mem == NULL || EXTRA_CONSTRAINT_STR (mem, c, constraint)))
+      enum constraint_num cn = lookup_constraint (constraint);
+      if (insn_extra_memory_constraint (cn)
+	  && (mem == NULL || constraint_satisfied_p (mem, cn)))
 	return true;
-#endif
     }
   return false;
 }
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/reload1.c	2014-06-05 21:45:00.217282830 +0100
@@ -1437,13 +1437,15 @@  maybe_fix_stack_asms (void)
 		  break;
 
 		default:
-		  if (EXTRA_ADDRESS_CONSTRAINT (c, p))
+		  enum constraint_num cn = lookup_constraint (p);
+		  if (insn_extra_address_constraint (cn))
 		    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)];
+		      [reg_class_for_constraint (cn)];
+		  break;
 		}
 	      p += CONSTRAINT_LEN (c, p);
 	    }
Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/stmt.c	2014-06-05 21:45:00.210282768 +0100
@@ -322,12 +322,11 @@  parse_output_constraint (const char **co
       default:
 	if (!ISALPHA (*p))
 	  break;
-	if (REG_CLASS_FROM_CONSTRAINT (*p, p) != NO_REGS)
+	enum constraint_num cn = lookup_constraint (p);
+	if (reg_class_for_constraint (cn) != NO_REGS
+	    || insn_extra_address_constraint (cn))
 	  *allows_reg = true;
-#ifdef EXTRA_CONSTRAINT_STR
-	else if (EXTRA_ADDRESS_CONSTRAINT (*p, p))
-	  *allows_reg = true;
-	else if (EXTRA_MEMORY_CONSTRAINT (*p, p))
+	else if (insn_extra_memory_constraint (cn))
 	  *allows_mem = true;
 	else
 	  {
@@ -337,7 +336,6 @@  parse_output_constraint (const char **co
 	    *allows_reg = true;
 	    *allows_mem = true;
 	  }
-#endif
 	break;
       }
 
@@ -454,13 +452,11 @@  parse_input_constraint (const char **con
 	    error ("invalid punctuation %qc in constraint", constraint[j]);
 	    return false;
 	  }
-	if (REG_CLASS_FROM_CONSTRAINT (constraint[j], constraint + j)
-	    != NO_REGS)
-	  *allows_reg = true;
-#ifdef EXTRA_CONSTRAINT_STR
-	else if (EXTRA_ADDRESS_CONSTRAINT (constraint[j], constraint + j))
+	enum constraint_num cn = lookup_constraint (constraint + j);
+	if (reg_class_for_constraint (cn) != NO_REGS
+	    || insn_extra_address_constraint (cn))
 	  *allows_reg = true;
-	else if (EXTRA_MEMORY_CONSTRAINT (constraint[j], constraint + j))
+	else if (insn_extra_memory_constraint (cn))
 	  *allows_mem = true;
 	else
 	  {
@@ -470,7 +466,6 @@  parse_input_constraint (const char **con
 	    *allows_reg = true;
 	    *allows_mem = true;
 	  }
-#endif
 	break;
       }
 
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/targhooks.c	2014-06-05 21:45:00.217282830 +0100
@@ -936,8 +936,8 @@  default_secondary_reload (bool in_p ATTR
 	      insn_letter = *insn_constraint;
 	      insn_class
 		= (insn_letter == 'r' ? GENERAL_REGS
-		   : REG_CLASS_FROM_CONSTRAINT ((unsigned char) insn_letter,
-						insn_constraint));
+		   : (reg_class_for_constraint
+		      (lookup_constraint (insn_constraint))));
 	      gcc_assert (insn_class != NO_REGS);
 	    }
 
@@ -954,8 +954,8 @@  default_secondary_reload (bool in_p ATTR
 	  scratch_letter = *scratch_constraint;
 	  scratch_class
 	    = (scratch_letter == 'r' ? GENERAL_REGS
-	       : REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter,
-					    scratch_constraint));
+	       : (reg_class_for_constraint
+		  (lookup_constraint (scratch_constraint))));
 
 	  if (reg_class_subset_p (reload_class, insn_class))
 	    {
Index: gcc/config/m32c/m32c.c
===================================================================
--- gcc/config/m32c/m32c.c	2014-06-05 21:06:52.721540056 +0100
+++ gcc/config/m32c/m32c.c	2014-06-05 21:45:00.219282847 +0100
@@ -854,7 +854,7 @@  #define IS_PSEUDO(rtx,strict) (!strict &
 
 #define A0_OR_PSEUDO(x) (IS_REG(x, A0_REGNO) || REGNO (x) >= FIRST_PSEUDO_REGISTER)
 
-/* Implements EXTRA_CONSTRAINT_STR (see next function too).  'S' is
+/* Implements matching for constraints (see next function too).  'S' is
    for memory constraints, plus "Rpa" for PARALLEL rtx's we use for
    call return values.  */
 bool
Index: gcc/config/sparc/constraints.md
===================================================================
--- gcc/config/sparc/constraints.md	2014-06-05 21:06:52.721540056 +0100
+++ gcc/config/sparc/constraints.md	2014-06-05 21:45:00.220282856 +0100
@@ -171,7 +171,7 @@  (define_memory_constraint "T"
 ;; define_register_constraint would.  This currently means that we cannot
 ;; use LRA on Sparc, since the constraint processing of LRA really depends
 ;; upon whether an extra constraint is for registers or not.  It uses
-;; REG_CLASS_FROM_CONSTRAINT, and checks it against NO_REGS.
+;; reg_class_for_constraint, and checks it against NO_REGS.
 (define_constraint "U"
  "Pseudo-register or hard even-numbered integer register"
  (and (match_test "TARGET_ARCH32")