diff mbox

[8/8] Add a common .md file and define standard constraints there

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

Commit Message

Richard Sandiford June 5, 2014, 9:43 p.m. UTC
This final patch uses a common .md file to define all standard
constraints except 'g'.  It then gets rid of explicit case statements
for the standard constraints, except in two cases:

(1) recog.c:asm_operand_ok still needs to handle 'o' specially for
    targets like ia64 that don't have offsettable addresses.  See the
    comment there for justification.

(2) the trickier cases in reload.  I'm not changing those more than I have to.

I did wonder about defining a new rtl construct that could be used for 'g',
so that even that special case goes away.  In the end I think it would be
a false abstraction though.  No other constraint allows (or IMO should allow)
all three of a register class, a base-reloadable memory and a constant,
so handling it in the lookup_constraint paths would make things more
complicated rather than less.

Note that the s390 'e' constraint is TARGET_MEM_CONSTRAINT, which is now
defined in the common file.

I put the common .md file in the main gcc/ directory by analogy with
defaults.h and common.opt.  It could instead go in config/ or config/common/,
if those sound better.

Richard


gcc/
	* common.md: New file.
	* doc/md.texi: Update description of generic, machine-independent
	constraints.
	* config/s390/constraints.md (e): Delete.
	* Makefile.in (md_file): Include common.md.
	* config/m32c/t-m32c (md_file): Likewise.
	* genpreds.c (general_mem): New array.
	(generic_constraint_letters): Remove constraints now defined by
	common.md.
	(add_constraint): Map TARGET_MEM_CONSTRAINT to general_mem.
	Allow the first character to be '<' or '>' as well.
	* genoutput.c (general_mem): New array.
	(indep_constraints): Remove constraints now defined by common.md.
	(note_constraint): Map TARGET_MEM_CONSTRAINT to general_mem.
	Remove special handling of 'm'.
	* ira-costs.c (record_reg_classes): Remove special handling of
	constraints now defined by common.md.
	* ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise.
	* ira-lives.c (single_reg_class): Likewise.
	(ira_implicitly_set_insn_hard_regs): Likewise.
	* lra-constraints.c (reg_class_from_constraints): Likewise.
	(process_alt_operands, process_address, curr_insn_transform): Likewise.
	* postreload.c (reload_cse_simplify_operands): Likewise.
	* reload.c (push_secondary_reload, scratch_reload_class)
	(find_reloads, alternative_allows_const_pool_ref): Likewise.
	* reload1.c (maybe_fix_stack_asms): Likewise.
	* targhooks.c (default_secondary_reload): Likewise.
	* stmt.c (parse_output_constraint): Likewise.
	* recog.c (preprocess_constraints): Likewise.
	(constrain_operands, peep2_find_free_register): Likewise.
	(asm_operand_ok): Likewise, but add a comment saying why 'o'
	must be handled specially.

Comments

Jeff Law June 10, 2014, 8:59 p.m. UTC | #1
On 06/05/14 15:43, Richard Sandiford wrote:
> This final patch uses a common .md file to define all standard
> constraints except 'g'.  It then gets rid of explicit case statements
> for the standard constraints, except in two cases:
>
> (1) recog.c:asm_operand_ok still needs to handle 'o' specially for
>      targets like ia64 that don't have offsettable addresses.  See the
>      comment there for justification.
>
> (2) the trickier cases in reload.  I'm not changing those more than I have to.
Can't argue with #2 ;-)  reload gets less and less important every day, 
so I see less and less value hacking too much on it.

>
> I did wonder about defining a new rtl construct that could be used for 'g',
> so that even that special case goes away.  In the end I think it would be
> a false abstraction though.  No other constraint allows (or IMO should allow)
> all three of a register class, a base-reloadable memory and a constant,
> so handling it in the lookup_constraint paths would make things more
> complicated rather than less.
OK.

>
> Note that the s390 'e' constraint is TARGET_MEM_CONSTRAINT, which is now
> defined in the common file.
>
> I put the common .md file in the main gcc/ directory by analogy with
> defaults.h and common.opt.  It could instead go in config/ or config/common/,
> if those sound better.
Seems fine to me, I don't feel a need to bikeshed here.


Does the comment before indep_constraints in genoutput need updating? 
The constraints in common.md are machine independent, but aren't listed 
in indep_constraints in genoutput.c

Approved with whatever language you want to use for that comment.

Jeff
Richard Sandiford June 11, 2014, 5 p.m. UTC | #2
Thanks for the reviews.

Jeff Law <law@redhat.com> writes:
> Does the comment before indep_constraints in genoutput need updating? 
> The constraints in common.md are machine independent, but aren't listed 
> in indep_constraints in genoutput.c

Yeah, good catch.  I changed it to:

/* All machine-independent constraint characters (except digits) that
   are handled outside the define*_constraint mechanism.  */
static const char indep_constraints[] = ",=+%*?!#&g";

Also in genpreds.c:

/* Contraint letters that have a special meaning and that cannot be used
   in define*_constraints.  */
static const char generic_constraint_letters[] = "g";

Richard
Segher Boessenkool June 12, 2014, 7:24 p.m. UTC | #3
On Thu, Jun 05, 2014 at 10:43:25PM +0100, Richard Sandiford wrote:
> This final patch uses a common .md file to define all standard
> constraints except 'g'.

I had a look at what targets still use "g".  Note: there can be
errors in this, it's all based on  \<g[,"]  :-)

* frv and mcore use "g" in commented-out patterns;
* cr16, mcore, picochip, rl78, and sh use "g" where they mean "rm"
  or "m";
* m68k uses it (in a dbne pattern) where the C template splits
  the "r", "m", "i" cases again;
* bfin, fr30, h8300, m68k, rs6000, and v850 use it as the second
  operand (# bytes pushed) of the call patterns; that operand is
  unused in all these cases, could just be "";
* cris, m68k, pdp11, and vax actually use "g".

So it won't be all that much work to completely get rid of "g".
Do we want that?


Segher
Paul Koning June 12, 2014, 7:39 p.m. UTC | #4
On Jun 12, 2014, at 3:24 PM, Segher Boessenkool <segher@kernel.crashing.org> wrote:

> On Thu, Jun 05, 2014 at 10:43:25PM +0100, Richard Sandiford wrote:
>> This final patch uses a common .md file to define all standard
>> constraints except 'g'.
> 
> I had a look at what targets still use "g".  Note: there can be
> errors in this, it's all based on  \<g[,"]  :-)
> 
> * frv and mcore use "g" in commented-out patterns;
> * cr16, mcore, picochip, rl78, and sh use "g" where they mean "rm"
>  or "m";
> * m68k uses it (in a dbne pattern) where the C template splits
>  the "r", "m", "i" cases again;
> * bfin, fr30, h8300, m68k, rs6000, and v850 use it as the second
>  operand (# bytes pushed) of the call patterns; that operand is
>  unused in all these cases, could just be "";
> * cris, m68k, pdp11, and vax actually use "g".
> 
> So it won't be all that much work to completely get rid of "g".
> Do we want that?

Is it simply a matter of replacing “g” by “mri”?  That’s what the doc suggests.  Or is there more to the story than that?

	paul
Segher Boessenkool June 12, 2014, 9:18 p.m. UTC | #5
> > * cris, m68k, pdp11, and vax actually use "g".
> > 
> > So it won't be all that much work to completely get rid of "g".
> > Do we want that?
> 
> Is it simply a matter of replacing “g” by “mri”?  That’s what the doc suggests.  Or is there more to the story than that?

As far as I know "g" and "rmi" are equivalent, yes.  "g" is easier to
type and read if you use it a lot (only ancient targets really); the
compiler will probably become somewhat slower for those targets, and
perhaps somewhat faster for all others.  Hard to say without doing the
work and measuring the result :-)


Segher
Steve Ellcey June 13, 2014, 8:06 p.m. UTC | #6
Richard,

Something in these constraint patches broke my mips16 build (I cannot
build glibc in mips16 mode).  I have cut down a test case and verified
that the problem started with this checkin:

2014-06-11  Richard Sandiford  <rdsandiford@googlemail.com>

	* common.md: New file.
	* doc/md.texi: Update description of generic, machine-independent
	constraints.
	* config/s390/constraints.md (e): Delete.
	* Makefile.in (md_file): Include common.md.
	* config/m32c/t-m32c (md_file): Likewise.
	* genpreds.c (general_mem): New array.
	(etc)

Attached is a small test case (its ugly but it comes from vfscanf in glibc) that
fails to compile for me with these options:

  -mips32r2 -mips16 -mabi=32 -std=gnu99 -fgnu89-inline -O2 -c x.c

Error message:

/tmp/ccAltddb.s: Assembler messages:
/tmp/ccAltddb.s:23: Error: invalid operands `sb $3,24($sp)'


Steve Ellcey
sellcey@mips.com
Richard Sandiford June 14, 2014, 9:58 a.m. UTC | #7
Segher Boessenkool <segher@kernel.crashing.org> writes:
>> > * cris, m68k, pdp11, and vax actually use "g".
>> > 
>> > So it won't be all that much work to completely get rid of "g".
>> > Do we want that?
>> 
>> Is it simply a matter of replacing “g” by “mri”?  That’s what the doc
>> suggests.  Or is there more to the story than that?
>
> As far as I know "g" and "rmi" are equivalent, yes.  "g" is easier to
> type and read if you use it a lot (only ancient targets really); the
> compiler will probably become somewhat slower for those targets, and
> perhaps somewhat faster for all others.  Hard to say without doing the
> work and measuring the result :-)

FWIW, I had a follow-on patch that created the recog_op_alt data at
build time and made the constraints field of that structure point to
CONSTRAINT_* bytes rather than raw strings.  That involved converting
"g" to "rmi" like you say and also meant adding CONSTRAINT_*s for "#"
and "?".  (Other non-operand characters can be dropped since the information
is given directly in the recog_op_alt.)

It didn't really seem to be much of a win though.

Richard
diff mbox

Patch

Index: gcc/common.md
===================================================================
--- /dev/null	2014-05-18 17:42:44.871287828 +0100
+++ gcc/common.md	2014-06-05 22:40:45.977752252 +0100
@@ -0,0 +1,95 @@ 
+;; Common GCC machine description file, shared by all targets.
+;; Copyright (C) 2014 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.  */
+
+(define_register_constraint "r" "GENERAL_REGS"
+  "Matches any general register.")
+
+(define_memory_constraint "TARGET_MEM_CONSTRAINT"
+  "Matches any valid memory."
+  (and (match_code "mem")
+       (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0),
+						 MEM_ADDR_SPACE (op))")))
+
+(define_memory_constraint "o"
+  "Matches an offsettable memory reference."
+  (and (match_code "mem")
+       (match_test "offsettable_nonstrict_memref_p (op)")))
+
+;; "V" matches TARGET_MEM_CONSTRAINTs that are rejected by "o".
+;; This means that it is not a memory constraint in the usual sense,
+;; since reloading the address into a base register would make the
+;; address offsettable.
+(define_constraint "V"
+  "Matches a non-offsettable memory reference."
+  (and (match_code "mem")
+       (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0),
+						 MEM_ADDR_SPACE (op))")
+       (not (match_test "offsettable_nonstrict_memref_p (op)"))))
+
+;; Like "V", this is not a memory constraint, since reloading the address
+;; into a base register would cause it not to match.
+(define_constraint "<"
+  "Matches a pre-dec or post-dec operand."
+  (and (match_code "mem")
+       (ior (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")
+       	    (match_test "GET_CODE (XEXP (op, 0)) == POST_DEC"))))
+
+;; See the comment for "<".
+(define_constraint ">"
+  "Matches a pre-inc or post-inc operand."
+  (and (match_code "mem")
+       (ior (match_test "GET_CODE (XEXP (op, 0)) == PRE_INC")
+       	    (match_test "GET_CODE (XEXP (op, 0)) == POST_INC"))))
+
+(define_address_constraint "p"
+  "Matches a general address."
+  (match_test "address_operand (op, VOIDmode)"))
+
+(define_constraint "i"
+  "Matches a general integer constant."
+  (and (match_test "CONSTANT_P (op)")
+       (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))
+
+(define_constraint "s"
+  "Matches a symbolic integer constant."
+  (and (match_test "CONSTANT_P (op)")
+       (match_test "!CONST_SCALAR_INT_P (op)")
+       (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))
+
+(define_constraint "n"
+  "Matches a non-symbolic integer constant."
+  (and (match_test "CONST_SCALAR_INT_P (op)")
+       (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))
+
+(define_constraint "E"
+  "Matches a floating-point constant."
+  (ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)")
+       (match_test "GET_CODE (op) == CONST_VECTOR
+		    && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT")))
+
+;; There is no longer a distinction between "E" and "F".
+(define_constraint "F"
+  "Matches a floating-point constant."
+  (ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)")
+       (match_test "GET_CODE (op) == CONST_VECTOR
+		    && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT")))
+
+(define_constraint "X"
+  "Matches anything."
+  (match_test "true"))
Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi	2014-06-05 22:32:31.329547134 +0100
+++ gcc/doc/md.texi	2014-06-05 22:40:45.995752404 +0100
@@ -4355,16 +4355,8 @@  Use this for constraints that should not
 It is occasionally useful to test a constraint from C code rather than
 implicitly via the constraint string in a @code{match_operand}.  The
 generated file @file{tm_p.h} declares a few interfaces for working
-with machine-specific constraints.  None of these interfaces work with
-the generic constraints described in @ref{Simple Constraints}.  This
-may change in the future.
-
-@strong{Warning:} @file{tm_p.h} may declare other functions that
-operate on constraints, besides the ones documented here.  Do not use
-those functions from machine-dependent code.  They exist to implement
-the old constraint interface that machine-independent components of
-the compiler still expect.  They will change or disappear in the
-future.
+with constraints.  At present these are defined for all constraints
+except @code{g} (which is equivalent to @code{general_operand}).
 
 Some valid constraint names are not valid C identifiers, so there is a
 mangling scheme for referring to them from C@.  Constraint names that
@@ -4391,17 +4383,14 @@  the variable @var{m} is a mangled constr
 a larger identifier).
 
 @deftp Enum constraint_num
-For each machine-specific constraint, there is a corresponding
+For each constraint except @code{g}, there is a corresponding
 enumeration constant: @samp{CONSTRAINT_} plus the mangled name of the
 constraint.  Functions that take an @code{enum constraint_num} as an
 argument expect one of these constants.
-
-Machine-independent constraints do not have associated constants.
-This may change in the future.
 @end deftp
 
 @deftypefun {inline bool} satisfies_constraint_@var{m} (rtx @var{exp})
-For each machine-specific, non-register constraint @var{m}, there is
+For each non-register constraint @var{m} except @code{g}, there is
 one of these functions; it returns @code{true} if @var{exp} satisfies the
 constraint.  These functions are only visible if @file{rtl.h} was included
 before @file{tm_p.h}.
Index: gcc/config/s390/constraints.md
===================================================================
--- gcc/config/s390/constraints.md	2014-06-05 22:32:31.329547134 +0100
+++ gcc/config/s390/constraints.md	2014-06-05 22:40:45.988752345 +0100
@@ -406,14 +406,6 @@  (define_memory_constraint "b"
                && s390_check_symref_alignment (XEXP (op, 0),
                                                GET_MODE_SIZE (GET_MODE (op)))"))
 
-(define_memory_constraint "e"
-  "Matches all memory references available on the current architecture
-level.  This constraint will never be used and using it in an inline
-assembly is *always* a bug since there is no instruction accepting all
-those addresses.  It just serves as a placeholder for a generic memory
-constraint."
-  (match_test "strict_memory_address_p (GET_MODE (op), op)"))
-
 ; This defines 'm' as normal memory constraint.  This is only possible
 ; since the standard memory constraint is re-defined in s390.h using
 ; the TARGET_MEM_CONSTRAINT macro.
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	2014-06-05 22:32:31.329547134 +0100
+++ gcc/Makefile.in	2014-06-05 22:40:45.976752243 +0100
@@ -491,7 +491,7 @@  out_file=$(srcdir)/config/@out_file@
 out_object_file=@out_object_file@
 common_out_file=$(srcdir)/common/config/@common_out_file@
 common_out_object_file=@common_out_object_file@
-md_file=$(srcdir)/config/@md_file@
+md_file=$(srcdir)/common.md $(srcdir)/config/@md_file@
 tm_file_list=@tm_file_list@
 tm_include_list=@tm_include_list@
 tm_defines=@tm_defines@
Index: gcc/config/m32c/t-m32c
===================================================================
--- gcc/config/m32c/t-m32c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/config/m32c/t-m32c	2014-06-05 22:40:45.993752387 +0100
@@ -20,7 +20,7 @@ 
 
 # target-specific files
 
-md_file = md
+md_file = $(srcdir)/common.md md
 
 MD_FILES = m32c constraints predicates addsub bitops blkmov cond jump minmax mov muldiv prologue shift
 
Index: gcc/genpreds.c
===================================================================
--- gcc/genpreds.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/genpreds.c	2014-06-05 22:40:45.977752252 +0100
@@ -30,6 +30,8 @@  the Free Software Foundation; either ver
 #include "read-md.h"
 #include "gensupport.h"
 
+static char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 };
+
 /* Given a predicate expression EXP, from form NAME at line LINENO,
    verify that it does not contain any RTL constructs which are not
    valid in predicate definitions.  Returns true if EXP is
@@ -664,7 +666,7 @@  #define FOR_ALL_CONSTRAINTS(iter_) \
    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";
+static const char generic_constraint_letters[] = "g";
 
 /* Machine-independent code expects that constraints with these
    (initial) letters will allow only (a subset of all) CONST_INTs.  */
@@ -735,19 +737,12 @@  add_constraint (const char *name, const
   bool is_const_dbl;
   size_t namelen;
 
+  if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0)
+    name = general_mem;
+
   if (exp && validate_exp (exp, name, lineno))
     return;
 
-  if (!ISALPHA (name[0]) && name[0] != '_')
-    {
-      if (name[1] == '\0')
-	error_with_line (lineno, "constraint name '%s' is not "
-			 "a letter or underscore", name);
-      else
-	error_with_line (lineno, "constraint name '%s' does not begin "
-			 "with a letter or underscore", name);
-      return;
-    }
   for (p = name; *p; p++)
     if (!ISALNUM (*p))
       {
Index: gcc/genoutput.c
===================================================================
--- gcc/genoutput.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/genoutput.c	2014-06-05 22:40:45.978752260 +0100
@@ -98,6 +98,8 @@  Software Foundation; either version 3, o
 
 #define MAX_MAX_OPERANDS 40
 
+static char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 };
+
 static int n_occurrences		(int, const char *);
 static const char *strip_whitespace	(const char *);
 
@@ -208,7 +210,7 @@  struct constraint_data
 /* This is a complete list (unlike the one in genpreds.c) of constraint
    letters and modifiers with machine-independent meaning.  The only
    omission is digits, as these are handled specially.  */
-static const char indep_constraints[] = ",=+%*?!#&<>EFVXgimnoprs";
+static const char indep_constraints[] = ",=+%*?!#&g";
 
 static struct constraint_data *
 constraints_by_letter_table[1 << CHAR_BIT];
@@ -1151,13 +1153,13 @@  strip_whitespace (const char *s)
 note_constraint (rtx exp, int lineno)
 {
   const char *name = XSTR (exp, 0);
-  unsigned int namelen = strlen (name);
   struct constraint_data **iter, **slot, *new_cdata;
 
-  /* 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 (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0)
+    name = general_mem;
+  unsigned int namelen = strlen (name);
+
+  if (strchr (indep_constraints, name[0]))
     {
       if (name[1] == '\0')
 	error_with_line (lineno, "constraint letter '%s' cannot be "
Index: gcc/ira-costs.c
===================================================================
--- gcc/ira-costs.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/ira-costs.c	2014-06-05 22:40:45.979752269 +0100
@@ -645,8 +645,6 @@  record_reg_classes (int n_alts, int n_op
 	    {
 	      switch (c)
 		{
-		case ',':
-		  break;
 		case '*':
 		  /* Ignore the next letter for this pass.  */
 		  c = *++p;
@@ -654,72 +652,6 @@  record_reg_classes (int n_alts, int n_op
 
 		case '?':
 		  alt_cost += 2;
-		case '!':  case '#':  case '&':
-		case '0':  case '1':  case '2':  case '3':  case '4':
-		case '5':  case '6':  case '7':  case '8':  case '9':
-		  break;
-
-		case 'p':
-		  allows_addr = 1;
-		  win = address_operand (op, GET_MODE (op));
-		  /* We know this operand is an address, so we want it
-		     to be allocated to a register that can be the
-		     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':
-		  /* It doesn't seem worth distinguishing between
-		     offsettable and non-offsettable addresses
-		     here.  */
-		  insn_allows_mem[i] = allows_mem[i] = 1;
-		  if (MEM_P (op))
-		    win = 1;
-		  break;
-
-		case '<':
-		  if (MEM_P (op)
-		      && (GET_CODE (XEXP (op, 0)) == PRE_DEC
-			  || GET_CODE (XEXP (op, 0)) == POST_DEC))
-		    win = 1;
-		  break;
-
-		case '>':
-		  if (MEM_P (op)
-		      && (GET_CODE (XEXP (op, 0)) == PRE_INC
-			  || GET_CODE (XEXP (op, 0)) == POST_INC))
-		    win = 1;
-		  break;
-
-		case 'E':
-		case 'F':
-		  if (CONST_DOUBLE_AS_FLOAT_P (op) 
-		      || (GET_CODE (op) == CONST_VECTOR
-			  && (GET_MODE_CLASS (GET_MODE (op))
-			      == MODE_VECTOR_FLOAT)))
-		    win = 1;
-		  break;
-
-		case 's':
-		  if (CONST_SCALAR_INT_P (op)) 
-		    break;
-
-		case 'i':
-		  if (CONSTANT_P (op)
-		      && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
-		    win = 1;
-		  break;
-
-		case 'n':
-		  if (CONST_SCALAR_INT_P (op)) 
-		    win = 1;
-		  break;
-
-		case 'X':
-		  win = 1;
 		  break;
 
 		case 'g':
@@ -728,7 +660,6 @@  record_reg_classes (int n_alts, int n_op
 			  && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))))
 		    win = 1;
 		  insn_allows_mem[i] = allows_mem[i] = 1;
-		case 'r':
 		  classes[i] = ira_reg_class_subunion[classes[i]][GENERAL_REGS];
 		  break;
 
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/ira.c	2014-06-05 22:40:45.981752286 +0100
@@ -1835,9 +1835,6 @@  ira_setup_alts (rtx insn, HARD_REG_SET &
 		    len = 0;
 		    break;
 		  
-		  case '?':  case '!': case '*':  case '=':  case '+':
-		    break;
-		    
 		  case '%':
 		    /* We only support one commutative marker, the
 		       first one.  We already set commutative
@@ -1846,63 +1843,12 @@  ira_setup_alts (rtx insn, HARD_REG_SET &
 		      commutative = nop;
 		    break;
 
-		  case '&':
-		    break;
-		    
 		  case '0':  case '1':  case '2':  case '3':  case '4':
 		  case '5':  case '6':  case '7':  case '8':  case '9':
 		    goto op_success;
 		    break;
 		    
-		  case 'p':
 		  case 'g':
-		  case 'X':
-		  case TARGET_MEM_CONSTRAINT:
-		    goto op_success;
-		    break;
-		    
-		  case '<':
-		    if (MEM_P (op)
-			&& (GET_CODE (XEXP (op, 0)) == PRE_DEC
-			    || GET_CODE (XEXP (op, 0)) == POST_DEC))
-		    goto op_success;
-		    break;
-		    
-		  case '>':
-		    if (MEM_P (op)
-		      && (GET_CODE (XEXP (op, 0)) == PRE_INC
-			  || GET_CODE (XEXP (op, 0)) == POST_INC))
-		      goto op_success;
-		    break;
-		    
-		  case 'E':
-		  case 'F':
-		    if (CONST_DOUBLE_AS_FLOAT_P (op)
-			|| (GET_CODE (op) == CONST_VECTOR
-			    && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT))
-		      goto op_success;
-		    break;
-		    
-		  case 's':
-		    if (CONST_SCALAR_INT_P (op))
-		      break;
-		  case 'i':
-		    if (CONSTANT_P (op))
-		      goto op_success;
-		    break;
-		    
-		  case 'n':
-		    if (CONST_SCALAR_INT_P (op))
-		      goto op_success;
-		    break;
-		    
-		  case 'V':
-		    if (MEM_P (op) && ! offsettable_memref_p (op))
-		      goto op_success;
-		    break;
-		    
-		  case 'o':
-		  case 'r':
 		    goto op_success;
 		    break;
 		    
@@ -1992,21 +1938,9 @@  ira_get_dup_out_num (int op_num, HARD_RE
 	  else if (! ignore_p)
 	    switch (c)
 	      {
-	      case 'X':
-	      case 'p':
 	      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':
-	      case 'v': case 'w': case 'x': case 'y': case 'z':
-	      case 'A': case 'B': case 'C': case 'D':
-	      case 'Q': case 'R': case 'S': case 'T': case 'U':
-	      case 'W': case 'Y': case 'Z':
+	      default:
 		{
 		  enum constraint_num cn = lookup_constraint (str);
 		  enum reg_class cl = reg_class_for_constraint (cn);
Index: gcc/ira-lives.c
===================================================================
--- gcc/ira-lives.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/ira-lives.c	2014-06-05 22:40:45.981752286 +0100
@@ -771,60 +771,10 @@  single_reg_class (const char *constraint
     else if (enabled & 1)
       switch (c)
 	{
-	case ' ':
-	case '\t':
-	case '=':
-	case '+':
-	case '*':
-	case '&':
-	case '%':
-	case '!':
-	case '?':
-	  break;
-	case 'i':
-	  if (CONSTANT_P (op)
-	      || (equiv_const != NULL_RTX && CONSTANT_P (equiv_const)))
-	    return NO_REGS;
-	  break;
-
-	case 'n':
-	  if (CONST_SCALAR_INT_P (op)
-	      || (equiv_const != NULL_RTX && CONST_SCALAR_INT_P (equiv_const)))
-	    return NO_REGS;
-	  break;
-
-	case 's':
-	  if ((CONSTANT_P (op) && !CONST_SCALAR_INT_P (op))
-	      || (equiv_const != NULL_RTX
-		  && CONSTANT_P (equiv_const)
-		  && !CONST_SCALAR_INT_P (equiv_const)))
-	    return NO_REGS;
-	  break;
-
-	case 'E':
-	case 'F':
-	  if (CONST_DOUBLE_AS_FLOAT_P (op) 
-	      || (GET_CODE (op) == CONST_VECTOR
-		  && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT)
-	      || (equiv_const != NULL_RTX
-		  && (CONST_DOUBLE_AS_FLOAT_P (equiv_const)
-		      || (GET_CODE (equiv_const) == CONST_VECTOR
-			  && (GET_MODE_CLASS (GET_MODE (equiv_const))
-			      == MODE_VECTOR_FLOAT)))))
-	    return NO_REGS;
-	  break;
+	case 'g':
+	  return NO_REGS;
 
-	case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
-	case 'O': case 'P':
-	case 'G': case 'H':
-	case 'r':
-	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':
-	case 'v': case 'w': case 'x': case 'y': case 'z':
-	case 'A': case 'B': case 'C': case 'D':
-	case 'Q': case 'R': case 'S': case 'T': case 'U':
-	case 'W': case 'Y': case 'Z':
+	default:
 	  /* ??? Is this the best way to handle memory constraints?  */
 	  cn = lookup_constraint (constraints);
 	  if (insn_extra_memory_constraint (cn)
@@ -835,9 +785,7 @@  single_reg_class (const char *constraint
 		  && CONSTANT_P (equiv_const)
 		  && constraint_satisfied_p (equiv_const, cn)))
 	    return NO_REGS;
-	  next_cl = (c == 'r'
-		     ? GENERAL_REGS
-		     : reg_class_for_constraint (cn));
+	  next_cl = reg_class_for_constraint (cn);
 	  if (next_cl == NO_REGS)
 	    break;
 	  if (cl == NO_REGS
@@ -860,9 +808,6 @@  single_reg_class (const char *constraint
 	    return NO_REGS;
 	  cl = next_cl;
 	  break;
-
-	default:
-	  return NO_REGS;
 	}
   return cl;
 }
@@ -913,29 +858,17 @@  ira_implicitly_set_insn_hard_regs (HARD_
 	    else if (c == ',')
 	      enabled >>= 1;
 	    else if (enabled & 1)
-	      switch (c)
-		{
-		case 'r':
-		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':
-		case 'v': case 'w': case 'x': case 'y': case 'z':
-		case 'A': case 'B': case 'C': case 'D':
-		case 'Q': case 'R': case 'S': case 'T': case 'U':
-		case 'W': case 'Y': case 'Z':
-		  cl = (c == 'r'
-			? GENERAL_REGS
-			: reg_class_for_constraint (lookup_constraint (p)));
-		  if (cl != NO_REGS)
-		    {
-		      /* There is no register pressure problem if all of the
-			 regs in this class are fixed.  */
-		      int regno = ira_class_singleton[cl][mode];
-		      if (regno >= 0)
-			add_to_hard_reg_set (set, mode, regno);
-		    }
-		  break;
-		}
+	      {
+		cl = reg_class_for_constraint (lookup_constraint (p));
+		if (cl != NO_REGS)
+		  {
+		    /* There is no register pressure problem if all of the
+		       regs in this class are fixed.  */
+		    int regno = ira_class_singleton[cl][mode];
+		    if (regno >= 0)
+		      add_to_hard_reg_set (set, mode, regno);
+		  }
+	      }
 	}
     }
 }
Index: gcc/lra-constraints.c
===================================================================
--- gcc/lra-constraints.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/lra-constraints.c	2014-06-05 22:40:45.983752303 +0100
@@ -968,14 +968,7 @@  reg_class_from_constraints (const char *
       case ',':
 	return op_class;
 
-      case 'p':
-	op_class = (reg_class_subunion
-		    [op_class][base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
-					       ADDRESS, SCRATCH)]);
-	break;
-
       case 'g':
-      case 'r':
 	op_class = reg_class_subunion[op_class][GENERAL_REGS];
 	break;
 
@@ -1768,15 +1761,6 @@  process_alt_operands (int only_alternati
 		  c = '\0';
 		  break;
 
-		case '=':  case '+': case '?': case '*': case '!':
-		case ' ': case '\t':
-		  break;
-
-		case '%':
-		  /* We only support one commutative marker, the first
-		     one.  We already set commutative above.  */
-		  break;
-
 		case '&':
 		  early_clobber_p = true;
 		  break;
@@ -1909,105 +1893,11 @@  process_alt_operands (int only_alternati
 		    break;
 		  }
 
-		case 'p':
-		  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]);
-		    }
-		  win = true;
-		  badop = false;
-		  break;
-
-		case TARGET_MEM_CONSTRAINT:
-		  if (MEM_P (op) || spilled_pseudo_p (op))
-		    win = true;
-		  /* We can put constant or pseudo value into memory
-		     to satisfy the constraint.  */
-		  if (CONST_POOL_OK_P (mode, op) || REG_P (op))
-		    badop = false;
-		  constmemok = true;
-		  break;
-
-		case '<':
-		  if (MEM_P (op)
-		      && (GET_CODE (XEXP (op, 0)) == PRE_DEC
-			  || GET_CODE (XEXP (op, 0)) == POST_DEC))
-		    win = true;
-		  break;
-
-		case '>':
-		  if (MEM_P (op)
-		      && (GET_CODE (XEXP (op, 0)) == PRE_INC
-			  || GET_CODE (XEXP (op, 0)) == POST_INC))
-		    win = true;
-		  break;
-
-		  /* Memory op whose address is not offsettable.  */
-		case 'V':
-		  if (MEM_P (op)
-		      && ! offsettable_nonstrict_memref_p (op))
-		    win = true;
-		  break;
-
-		  /* Memory operand whose address is offsettable.  */
-		case 'o':
-		  if ((MEM_P (op)
-		       && offsettable_nonstrict_memref_p (op))
-		      || spilled_pseudo_p (op))
-		    win = true;
-		  /* We can put constant or pseudo value into memory
-		     or make memory address offsetable to satisfy the
-		     constraint.  */
-		  if (CONST_POOL_OK_P (mode, op) || MEM_P (op) || REG_P (op))
-		    badop = false;
-		  constmemok = true;
-		  offmemok = true;
-		  break;
-
-		case 'E':
-		case 'F':
-		  if (GET_CODE (op) == CONST_DOUBLE
-		      || (GET_CODE (op) == CONST_VECTOR
-			  && (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)))
-		    win = true;
-		  break;
-
-		case 's':
-		  if (CONST_SCALAR_INT_P (op))
-		    break;
-
-		case 'i':
-		  if (general_constant_p (op))
-		    win = true;
-		  break;
-
-		case 'n':
-		  if (CONST_SCALAR_INT_P (op))
-		    win = true;
-		  break;
-
-		case 'X':
-		  /* This constraint should be excluded by the fast
-		     track.  */
-		  gcc_unreachable ();
-		  break;
-
 		case 'g':
 		  if (MEM_P (op)
 		      || general_constant_p (op)
 		      || spilled_pseudo_p (op))
 		    win = true;
-		  /* Drop through into 'r' case.  */
-
-		case 'r':
 		  cl = GENERAL_REGS;
 		  goto reg;
 
@@ -2821,8 +2711,7 @@  process_address_1 (int nop, rtx *before,
   enum constraint_num cn = lookup_constraint (constraint);
   bool change_p;
 
-  if (constraint[0] == 'p'
-      || insn_extra_address_constraint (cn))
+  if (insn_extra_address_constraint (cn))
     decompose_lea_address (&ad, curr_id->operand_loc[nop]);
   else if (MEM_P (op))
     decompose_mem_address (&ad, op);
@@ -2853,8 +2742,7 @@  process_address_1 (int nop, rtx *before,
 
   /* Target hooks sometimes don't treat extra-constraint addresses as
      legitimate address_operands, so handle them specially.  */
-  if (constraint[0] != 'p'
-      && insn_extra_address_constraint (cn)
+  if (insn_extra_address_constraint (cn)
       && satisfies_address_constraint_p (&ad, cn))
     return change_p;
 
@@ -3569,8 +3457,6 @@  curr_insn_transform (void)
 		 (c = *constraint) && c != ',' && c != '#';
 		 constraint += CONSTRAINT_LEN (c, constraint))
 	      {
-		if (c == TARGET_MEM_CONSTRAINT || c == 'o')
-		  break;
 		enum constraint_num cn = lookup_constraint (constraint);
 		if (insn_extra_memory_constraint (cn)
 		    && satisfies_memory_constraint_p (tem, cn))
Index: gcc/postreload.c
===================================================================
--- gcc/postreload.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/postreload.c	2014-06-05 22:40:45.987752337 +0100
@@ -553,22 +553,8 @@  reload_cse_simplify_operands (rtx insn,
 
 	      switch (c)
 		{
-		case '=':  case '+':  case '?':
-		case '#':  case '&':  case '!':
-		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;
-
-		case 'g': case 'r':
-		  rclass = reg_class_subunion[(int) rclass][(int) GENERAL_REGS];
+		case 'g':
+		  rclass = reg_class_subunion[rclass][GENERAL_REGS];
 		  break;
 
 		default:
Index: gcc/reload.c
===================================================================
--- gcc/reload.c	2014-06-05 22:40:14.946489460 +0100
+++ gcc/reload.c	2014-06-05 22:40:45.992752379 +0100
@@ -328,7 +328,6 @@  push_secondary_reload (int in_p, rtx x,
   enum reload_type secondary_type;
   int s_reload, t_reload = -1;
   const char *scratch_constraint;
-  char letter;
   secondary_reload_info sri;
 
   if (type == RELOAD_FOR_INPUT_ADDRESS
@@ -399,10 +398,8 @@  push_secondary_reload (int in_p, rtx x,
       scratch_constraint++;
       if (*scratch_constraint == '&')
 	scratch_constraint++;
-      letter = *scratch_constraint;
-      scratch_class = (letter == 'r' ? GENERAL_REGS
-		       : (reg_class_for_constraint
-			  (lookup_constraint (scratch_constraint))));
+      scratch_class = (reg_class_for_constraint
+		       (lookup_constraint (scratch_constraint)));
 
       rclass = scratch_class;
       mode = insn_data[(int) icode].operand[2].mode;
@@ -548,7 +545,6 @@  enum reg_class
 scratch_reload_class (enum insn_code icode)
 {
   const char *scratch_constraint;
-  char scratch_letter;
   enum reg_class rclass;
 
   gcc_assert (insn_data[(int) icode].n_operands == 3);
@@ -557,9 +553,6 @@  scratch_reload_class (enum insn_code ico
   scratch_constraint++;
   if (*scratch_constraint == '&')
     scratch_constraint++;
-  scratch_letter = *scratch_constraint;
-  if (scratch_letter == 'r')
-    return GENERAL_REGS;
   rclass = reg_class_for_constraint (lookup_constraint (scratch_constraint));
   gcc_assert (rclass != NO_REGS);
   return rclass;
@@ -2850,9 +2843,8 @@  find_reloads (rtx insn, int replace, int
       if (*constraints[i] == 0)
 	/* Ignore things like match_operator operands.  */
 	;
-      else if (constraints[i][0] == 'p'
-	       || (insn_extra_address_constraint
-		   (lookup_constraint (constraints[i]))))
+      else if (insn_extra_address_constraint
+	       (lookup_constraint (constraints[i])))
 	{
 	  address_operand_reloaded[i]
 	    = find_reloads_address (recog_data.operand_mode[i], (rtx*) 0,
@@ -3209,14 +3201,6 @@  find_reloads (rtx insn, int replace, int
 		    c = '\0';
 		    break;
 
-		  case '=':  case '+':  case '*':
-		    break;
-
-		  case '%':
-		    /* We only support one commutative marker, the first
-		       one.  We already set commutative above.  */
-		    break;
-
 		  case '?':
 		    reject += 6;
 		    break;
@@ -3425,29 +3409,6 @@  find_reloads (rtx insn, int replace, int
 		    earlyclobber = 1, this_earlyclobber = 1;
 		    break;
 
-		  case 'E':
-		  case 'F':
-		    if (CONST_DOUBLE_AS_FLOAT_P (operand)
-			|| (GET_CODE (operand) == CONST_VECTOR
-			    && (GET_MODE_CLASS (GET_MODE (operand))
-				== MODE_VECTOR_FLOAT)))
-		      win = 1;
-		    break;
-
-		  case 's':
-		    if (CONST_SCALAR_INT_P (operand))
-		      break;
-		  case 'i':
-		    if (CONSTANT_P (operand)
-			&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand)))
-		      win = 1;
-		    break;
-
-		  case 'n':
-		    if (CONST_SCALAR_INT_P (operand))
-		      win = 1;
-		    break;
-
 		  case 'X':
 		    force_reload = 0;
 		    win = 1;
@@ -3468,9 +3429,6 @@  find_reloads (rtx insn, int replace, int
 			    || (REGNO (operand) >= FIRST_PSEUDO_REGISTER
 				&& reg_renumber[REGNO (operand)] < 0)))
 		      win = 1;
-		    /* Drop through into 'r' case.  */
-
-		  case 'r':
 		    cl = GENERAL_REGS;
 		    goto reg;
 
@@ -4677,8 +4635,6 @@  alternative_allows_const_pool_ref (rtx m
   for (; (c = *constraint) && c != ',' && c != '#';
        constraint += CONSTRAINT_LEN (c, constraint))
     {
-      if (c == TARGET_MEM_CONSTRAINT || c == 'o')
-	return true;
       enum constraint_num cn = lookup_constraint (constraint);
       if (insn_extra_memory_constraint (cn)
 	  && (mem == NULL || constraint_satisfied_p (mem, cn)))
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/reload1.c	2014-06-05 22:40:45.990752362 +0100
@@ -1417,22 +1417,7 @@  maybe_fix_stack_asms (void)
 
 	      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':
-		  cls = (int) reg_class_subunion[cls]
-		      [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
-					     ADDRESS, SCRATCH)];
-		  break;
-
 		case 'g':
-		case 'r':
 		  cls = (int) reg_class_subunion[cls][(int) GENERAL_REGS];
 		  break;
 
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/targhooks.c	2014-06-05 22:40:45.987752337 +0100
@@ -919,7 +919,6 @@  default_secondary_reload (bool in_p ATTR
       else if (icode != CODE_FOR_nothing)
 	{
 	  const char *insn_constraint, *scratch_constraint;
-	  char insn_letter, scratch_letter;
 	  enum reg_class insn_class, scratch_class;
 
 	  gcc_assert (insn_data[(int) icode].n_operands == 3);
@@ -933,11 +932,8 @@  default_secondary_reload (bool in_p ATTR
 		  gcc_assert (*insn_constraint == '=');
 		  insn_constraint++;
 		}
-	      insn_letter = *insn_constraint;
-	      insn_class
-		= (insn_letter == 'r' ? GENERAL_REGS
-		   : (reg_class_for_constraint
-		      (lookup_constraint (insn_constraint))));
+	      insn_class = (reg_class_for_constraint
+			    (lookup_constraint (insn_constraint)));
 	      gcc_assert (insn_class != NO_REGS);
 	    }
 
@@ -951,11 +947,8 @@  default_secondary_reload (bool in_p ATTR
 	  scratch_constraint++;
 	  if (*scratch_constraint == '&')
 	    scratch_constraint++;
-	  scratch_letter = *scratch_constraint;
-	  scratch_class
-	    = (scratch_letter == 'r' ? GENERAL_REGS
-	       : (reg_class_for_constraint
-		  (lookup_constraint (scratch_constraint))));
+	  scratch_class = (reg_class_for_constraint
+			   (lookup_constraint (scratch_constraint)));
 
 	  if (reg_class_subset_p (reload_class, insn_class))
 	    {
Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/stmt.c	2014-06-05 22:40:45.986752328 +0100
@@ -286,10 +286,6 @@  parse_output_constraint (const char **co
 	  }
 	break;
 
-      case 'V':  case TARGET_MEM_CONSTRAINT:  case 'o':
-	*allows_mem = true;
-	break;
-
       case '?':  case '!':  case '*':  case '&':  case '#':
       case 'E':  case 'F':  case 'G':  case 'H':
       case 's':  case 'i':  case 'n':
@@ -315,10 +311,6 @@  parse_output_constraint (const char **co
 	*allows_mem = true;
 	break;
 
-      case 'p': case 'r':
-	*allows_reg = true;
-	break;
-
       default:
 	if (!ISALPHA (*p))
 	  break;
@@ -383,10 +375,6 @@  parse_input_constraint (const char **con
 	  }
 	break;
 
-      case 'V':  case TARGET_MEM_CONSTRAINT:  case 'o':
-	*allows_mem = true;
-	break;
-
       case '<':  case '>':
       case '?':  case '!':  case '*':  case '#':
       case 'E':  case 'F':  case 'G':  case 'H':
@@ -437,10 +425,6 @@  parse_input_constraint (const char **con
 	}
 	/* Fall through.  */
 
-      case 'p':  case 'r':
-	*allows_reg = true;
-	break;
-
       case 'g':  case 'X':
 	*allows_reg = true;
 	*allows_mem = true;
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	2014-06-05 22:32:31.329547134 +0100
+++ gcc/recog.c	2014-06-05 22:40:45.985752320 +0100
@@ -1737,15 +1737,6 @@  asm_operand_ok (rtx op, const char *cons
 	case ',':
 	  constraint++;
 	  continue;
-	case '=':
-	case '+':
-	case '*':
-	case '%':
-	case '!':
-	case '#':
-	case '&':
-	case '?':
-	  break;
 
 	case '0': case '1': case '2': case '3': case '4':
 	case '5': case '6': case '7': case '8': case '9':
@@ -1774,98 +1765,47 @@  asm_operand_ok (rtx op, const char *cons
 	    }
 	  continue;
 
-	case 'p':
-	  if (address_operand (op, VOIDmode))
-	    result = 1;
-	  break;
-
-	case TARGET_MEM_CONSTRAINT:
-	case 'V': /* non-offsettable */
-	  if (memory_operand (op, VOIDmode))
-	    result = 1;
-	  break;
-
+	  /* The rest of the compiler assumes that reloading the address
+	     of a MEM into a register will make it fit an 'o' constraint.
+	     That is, if it sees a MEM operand for an 'o' constraint,
+	     it assumes that (mem (base-reg)) will fit.
+
+	     That assumption fails on targets that don't have offsettable
+	     addresses at all.  We therefore need to treat 'o' asm
+	     constraints as a special case and only accept operands that
+	     are already offsettable, thus proving that at least one
+	     offsettable address exists.  */
 	case 'o': /* offsettable */
 	  if (offsettable_nonstrict_memref_p (op))
 	    result = 1;
 	  break;
 
-	case '<':
-	  /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed to exist,
-	     excepting those that expand_call created.  Further, on some
-	     machines which do not have generalized auto inc/dec, an inc/dec
-	     is not a memory_operand.
-
-	     Match any memory and hope things are resolved after reload.  */
-
-	  if (MEM_P (op)
-	      && (1
-		  || GET_CODE (XEXP (op, 0)) == PRE_DEC
-		  || GET_CODE (XEXP (op, 0)) == POST_DEC))
-	    result = 1;
-#ifdef AUTO_INC_DEC
-	  incdec_ok = true;
-#endif
-	  break;
-
-	case '>':
-	  if (MEM_P (op)
-	      && (1
-		  || GET_CODE (XEXP (op, 0)) == PRE_INC
-		  || GET_CODE (XEXP (op, 0)) == POST_INC))
-	    result = 1;
-#ifdef AUTO_INC_DEC
-	  incdec_ok = true;
-#endif
-	  break;
-
-	case 'E':
-	case 'F':
-	  if (CONST_DOUBLE_AS_FLOAT_P (op) 
-	      || (GET_CODE (op) == CONST_VECTOR
-		  && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT))
-	    result = 1;
-	  break;
-
-	case 's':
-	  if (CONST_SCALAR_INT_P (op))
-	    break;
-	  /* Fall through.  */
-
-	case 'i':
-	  if (CONSTANT_P (op) && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
-	    result = 1;
-	  break;
-
-	case 'n':
-	  if (CONST_SCALAR_INT_P (op))
-	    result = 1;
-	  break;
-
-	case 'X':
-	  result = 1;
-	  break;
-
 	case 'g':
 	  if (general_operand (op, VOIDmode))
 	    result = 1;
 	  break;
 
-	case 'r':
-	reg:
-	  if (!result
-	      && GET_MODE (op) != BLKmode
-	      && register_operand (op, VOIDmode))
-	    result = 1;
-	  break;
+#ifdef AUTO_INC_DEC
+	case '<':
+	case '>':
+	  /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed
+	     to exist, excepting those that expand_call created.  Further,
+	     on some machines which do not have generalized auto inc/dec,
+	     an inc/dec is not a memory_operand.
 
+	     Match any memory and hope things are resolved after reload.  */
+	  incdec_ok = true;
+#endif
 	default:
 	  cn = lookup_constraint (constraint);
 	  switch (get_constraint_type (cn))
 	    {
 	    case CT_REGISTER:
-	      if (reg_class_for_constraint (cn) != NO_REGS)
-		goto reg;
+	      if (!result
+		  && reg_class_for_constraint (cn) != NO_REGS
+		  && GET_MODE (op) != BLKmode
+		  && register_operand (op, VOIDmode))
+		result = 1;
 	      break;
 
 	    case CT_CONST_INT:
@@ -2339,14 +2279,6 @@  preprocess_constraints (int n_operands,
 
 	      switch (c)
 		{
-		case '=': case '+': case '*': case '%':
-		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':
-		  /* These don't say anything we care about.  */
-		  break;
-
 		case '?':
 		  op_alt[i].reject += 6;
 		  break;
@@ -2367,22 +2299,11 @@  preprocess_constraints (int n_operands,
 		  }
 		  continue;
 
-		case TARGET_MEM_CONSTRAINT:
-		  op_alt[i].memory_ok = 1;
-		  break;
 		case 'X':
 		  op_alt[i].anything_ok = 1;
 		  break;
 
-		case 'p':
-		  op_alt[i].is_address = 1;
-		  op_alt[i].cl = reg_class_subunion[(int) op_alt[i].cl]
-		      [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
-					     ADDRESS, SCRATCH)];
-		  break;
-
 		case 'g':
-		case 'r':
 		  op_alt[i].cl =
 		   reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
 		  break;
@@ -2592,10 +2513,6 @@  constrain_operands (int strict)
 		c = '\0';
 		break;
 
-	      case '?':  case '!': case '*':  case '%':
-	      case '=':  case '+':
-		break;
-
 	      case '#':
 		/* Ignore rest of this alternative as far as
 		   constraint checking is concerned.  */
@@ -2695,106 +2612,10 @@  constrain_operands (int strict)
 		  win = 1;
 		break;
 
-	      case 'X':
-		/* This is used for a MATCH_SCRATCH in the cases when
-		   we don't actually need anything.  So anything goes
-		   any time.  */
-		win = 1;
-		break;
-
-	      case TARGET_MEM_CONSTRAINT:
-		/* Memory operands must be valid, to the extent
-		   required by STRICT.  */
-		if (MEM_P (op))
-		  {
-		    if (strict > 0
-			&& !strict_memory_address_addr_space_p
-			     (GET_MODE (op), XEXP (op, 0),
-			      MEM_ADDR_SPACE (op)))
-		      break;
-		    if (strict == 0
-			&& !memory_address_addr_space_p
-			     (GET_MODE (op), XEXP (op, 0),
-			      MEM_ADDR_SPACE (op)))
-		      break;
-		    win = 1;
-		  }
-		/* Before reload, accept what reload can turn into mem.  */
-		else if (strict < 0 && CONSTANT_P (op))
-		  win = 1;
-		/* During reload, accept a pseudo  */
-		else if (reload_in_progress && REG_P (op)
-			 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
-		  win = 1;
-		break;
-
-	      case '<':
-		if (MEM_P (op)
-		    && (GET_CODE (XEXP (op, 0)) == PRE_DEC
-			|| GET_CODE (XEXP (op, 0)) == POST_DEC))
-		  win = 1;
-		break;
-
-	      case '>':
-		if (MEM_P (op)
-		    && (GET_CODE (XEXP (op, 0)) == PRE_INC
-			|| GET_CODE (XEXP (op, 0)) == POST_INC))
-		  win = 1;
-		break;
-
-	      case 'E':
-	      case 'F':
-		if (CONST_DOUBLE_AS_FLOAT_P (op)
-		    || (GET_CODE (op) == CONST_VECTOR
-			&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT))
-		  win = 1;
-		break;
-
-	      case 's':
-		if (CONST_SCALAR_INT_P (op))
-		  break;
-	      case 'i':
-		if (CONSTANT_P (op))
-		  win = 1;
-		break;
-
-	      case 'n':
-		if (CONST_SCALAR_INT_P (op))
-		  win = 1;
-		break;
-
-	      case 'V':
-		if (MEM_P (op)
-		    && ((strict > 0 && ! offsettable_memref_p (op))
-			|| (strict < 0
-			    && !(CONSTANT_P (op) || MEM_P (op)))
-			|| (reload_in_progress
-			    && !(REG_P (op)
-				 && REGNO (op) >= FIRST_PSEUDO_REGISTER))))
-		  win = 1;
-		break;
-
-	      case 'o':
-		if ((strict > 0 && offsettable_memref_p (op))
-		    || (strict == 0 && offsettable_nonstrict_memref_p (op))
-		    /* Before reload, accept what reload can handle.  */
-		    || (strict < 0
-			&& (CONSTANT_P (op) || MEM_P (op)))
-		    /* During reload, accept a pseudo  */
-		    || (reload_in_progress && REG_P (op)
-			&& REGNO (op) >= FIRST_PSEUDO_REGISTER))
-		  win = 1;
-		break;
-
 	      default:
 		{
-		  enum reg_class cl;
-		  enum constraint_num cn = (c == 'r'
-					    ? CONSTRAINT__UNKNOWN
-					    : lookup_constraint (p));
-
-		  cl = (c == 'r'
-			? GENERAL_REGS : reg_class_for_constraint (cn));
+		  enum constraint_num cn = lookup_constraint (p);
+		  enum reg_class cl = reg_class_for_constraint (cn);
 		  if (cl != NO_REGS)
 		    {
 		      if (strict < 0
@@ -3227,8 +3048,7 @@  peep2_find_free_register (int from, int
       from = peep2_buf_position (from + 1);
     }
 
-  cl = (class_str[0] == 'r' ? GENERAL_REGS
-	: reg_class_for_constraint (lookup_constraint (class_str)));
+  cl = reg_class_for_constraint (lookup_constraint (class_str));
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {