Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi	2014-05-26 19:47:27.560682653 +0100
+++ gcc/doc/md.texi	2014-05-26 20:08:23.808948838 +0100
@@ -1589,7 +1589,9 @@ See, for example, the @samp{mulsi3} insn
 Declares the instruction to be commutative for this operand and the
 following operand.  This means that the compiler may interchange the
 two operands if that is the cheapest way to make all operands fit the
-constraints.
+constraints.  @samp{%} applies to all alternatives and must appear as
+the first character in the constraint.
+
 @ifset INTERNALS
 This is often used in patterns for addition instructions
 that really have only two operands: the result must go in one of the
Index: gcc/genoutput.c
===================================================================
--- gcc/genoutput.c	2014-05-26 19:47:27.560682653 +0100
+++ gcc/genoutput.c	2014-05-26 20:08:23.675947636 +0100
@@ -781,6 +781,11 @@ validate_insn_alternatives (struct data
 
 	for (p = d->operand[start].constraint; (c = *p); p += len)
 	  {
+	    if ((c == '%' || c == '=' || c == '+')
+		&& p != d->operand[start].constraint)
+	      error_with_line (d->lineno,
+			       "character '%c' can only be used at the"
+			       " beginning of a constraint string");
 #ifdef USE_MD_CONSTRAINTS
 	    if (ISSPACE (c) || strchr (indep_constraints, c))
 	      len = 1;
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2014-05-26 20:10:28.988080881 +0100
+++ gcc/ira.c	2014-05-26 20:10:32.773115124 +0100
@@ -1769,38 +1769,6 @@ setup_prohibited_mode_move_regs (void)
 }
 
 
-
-/* Return TRUE if the operand constraint STR is commutative.  */
-static bool
-commutative_constraint_p (const char *str)
-{
-  int curr_alt, c;
-  bool ignore_p;
-
-  for (ignore_p = false, curr_alt = 0;;)
-    {
-      c = *str;
-      if (c == '\0')
-	break;
-      str += CONSTRAINT_LEN (c, str);
-      if (c == '#' || !recog_data.alternative_enabled_p[curr_alt])
-	ignore_p = true;
-      else if (c == ',')
-	{
-	  curr_alt++;
-	  ignore_p = false;
-	}
-      else if (! ignore_p)
-	{
-	  /* Usually `%' is the first constraint character but the
-	     documentation does not require this.  */
-	  if (c == '%')
-	    return true;
-	}
-    }
-  return false;
-}
-
 /* Setup possible alternatives in ALTS for INSN.  */
 void
 ira_setup_alts (rtx insn, HARD_REG_SET &alts)
@@ -2101,10 +2069,9 @@ ira_get_dup_out_num (int op_num, HARD_RE
       if (use_commut_op_p)
 	break;
       use_commut_op_p = true;
-      if (commutative_constraint_p (recog_data.constraints[op_num]))
+      if (recog_data.constraints[op_num][0] == '%')
 	str = recog_data.constraints[op_num + 1];
-      else if (op_num > 0 && commutative_constraint_p (recog_data.constraints
-						       [op_num - 1]))
+      else if (op_num > 0 && recog_data.constraints[op_num - 1][0] == '%')
 	str = recog_data.constraints[op_num - 1];
       else
 	break;
Index: gcc/config/alpha/alpha.md
===================================================================
--- gcc/config/alpha/alpha.md	2014-05-26 19:47:27.560682653 +0100
+++ gcc/config/alpha/alpha.md	2014-05-26 20:08:23.697947834 +0100
@@ -4764,7 +4764,7 @@ (define_expand "movmemdi"
   "operands[4] = gen_rtx_SYMBOL_REF (Pmode, \"OTS$MOVE\");")
 
 (define_insn "*movmemdi_1"
-  [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
+  [(set (match_operand:BLK 0 "memory_operand" "=m,m")
 	(match_operand:BLK 1 "memory_operand" "m,m"))
    (use (match_operand:DI 2 "nonmemory_operand" "r,i"))
    (use (match_operand:DI 3 "immediate_operand"))
@@ -4831,7 +4831,7 @@ (define_expand "setmemdi"
 })
 
 (define_insn "*clrmemdi_1"
-  [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
+  [(set (match_operand:BLK 0 "memory_operand" "=m,m")
 		   (const_int 0))
    (use (match_operand:DI 1 "nonmemory_operand" "r,i"))
    (use (match_operand:DI 2 "immediate_operand"))
Index: gcc/config/arm/neon.md
===================================================================
--- gcc/config/arm/neon.md	2014-05-26 19:47:27.560682653 +0100
+++ gcc/config/arm/neon.md	2014-05-26 20:08:23.720948042 +0100
@@ -728,7 +728,7 @@ (define_insn "bic<mode>3_neon"
 
 ;; Compare to *anddi_notdi_di.
 (define_insn "bicdi3_neon"
-  [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
+  [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
 		(match_operand:DI 1 "s_register_operand" "w,0,r")))]
   "TARGET_NEON"
Index: gcc/config/vax/vax.md
===================================================================
--- gcc/config/vax/vax.md	2014-05-26 19:47:27.560682653 +0100
+++ gcc/config/vax/vax.md	2014-05-26 20:08:23.776948548 +0100
@@ -423,7 +423,7 @@ (define_expand "subdi3"
   "vax_expand_addsub_di_operands (operands, MINUS); DONE;")
 
 (define_insn "sbcdi3"
-  [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,=Rr")
+  [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr")
 	(minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I")
 		  (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))]
   "TARGET_QMATH"
Index: gcc/config/h8300/h8300.md
===================================================================
--- gcc/config/h8300/h8300.md	2014-05-26 19:47:27.560682653 +0100
+++ gcc/config/h8300/h8300.md	2014-05-26 20:08:23.791948684 +0100
@@ -3589,7 +3589,7 @@ (define_insn "*bstzhireg"
   [(set_attr "cc" "clobber")])
 
 (define_insn_and_split "*cmpstz"
-  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,+WU")
+  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
 			 (const_int 1)
 			 (match_operand:QI 1 "immediate_operand" "n,n"))
 	(match_operator:QI 2 "eqne_operator"
Index: gcc/config/arc/arc.md
===================================================================
--- gcc/config/arc/arc.md	2014-05-26 19:47:27.560682653 +0100
+++ gcc/config/arc/arc.md	2014-05-26 20:08:23.590946867 +0100
@@ -1698,7 +1698,7 @@ (define_insn "mac_600"
 
 (define_insn "mulsi_600"
   [(set (match_operand:SI 2 "mlo_operand" "")
-	(mult:SI (match_operand:SI 0 "register_operand"  "Rcq#q,c,c,%c")
+	(mult:SI (match_operand:SI 0 "register_operand"  "%Rcq#q,c,c,c")
 		 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
    (clobber (match_operand:SI 3 "mhi_operand" ""))]
   "TARGET_MUL64_SET"
@@ -1750,7 +1750,7 @@ (define_insn "mulsi3_600_lib"
 (define_insn "mulsidi_600"
   [(set (reg:DI MUL64_OUT_REG)
 	(mult:DI (sign_extend:DI
-		   (match_operand:SI 0 "register_operand"  "Rcq#q,c,c,%c"))
+		   (match_operand:SI 0 "register_operand"  "%Rcq#q,c,c,c"))
 		 (sign_extend:DI
 ; assembler issue for "I", see mulsi_600
 ;		   (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,Cal"))))]
@@ -1766,7 +1766,7 @@ (define_insn "mulsidi_600"
 (define_insn "umulsidi_600"
   [(set (reg:DI MUL64_OUT_REG)
 	(mult:DI (zero_extend:DI
-		   (match_operand:SI 0 "register_operand"  "c,c,%c"))
+		   (match_operand:SI 0 "register_operand"  "%c,c,c"))
 		 (sign_extend:DI
 ; assembler issue for "I", see mulsi_600
 ;		   (match_operand:SI 1 "register_operand" "cL,I,Cal"))))]
@@ -4134,7 +4134,7 @@ (define_insn "swap"
 
 ;; FIXME: an intrinsic for multiply is daft.  Can we remove this?
 (define_insn "mul64"
-  [(unspec [(match_operand:SI 0 "general_operand" "q,r,r,%r")
+  [(unspec [(match_operand:SI 0 "general_operand" "%q,r,r,r")
 		     (match_operand:SI 1 "general_operand" "q,rL,I,Cal")]
 		   UNSPEC_MUL64)]
   "TARGET_MUL64_SET"
Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md	2014-05-26 19:47:27.560682653 +0100
+++ gcc/config/arm/arm.md	2014-05-26 20:08:23.629947220 +0100
@@ -3169,7 +3169,7 @@ (define_expand "xordi3"
 
 (define_insn_and_split "*xordi3_insn"
   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
-	(xor:DI (match_operand:DI 1 "s_register_operand" "w ,%0,r ,0 ,r ,w")
+	(xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
 		(match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
   "TARGET_32BIT && !TARGET_IWMMXT"
 {
Index: gcc/config/nds32/nds32.md
===================================================================
--- gcc/config/nds32/nds32.md	2014-05-26 19:47:27.560682653 +0100
+++ gcc/config/nds32/nds32.md	2014-05-26 20:08:23.663947527 +0100
@@ -261,7 +261,7 @@ (define_insn "extend<mode>si2"
 
 (define_insn "add<mode>3"
   [(set (match_operand:QIHISI 0 "register_operand"                   "=   d,    l,    d,    l,  d, l,    k,    l,    r, r")
-	(plus:QIHISI (match_operand:QIHISI 1 "register_operand"      "    0,    l,    0,    l, %0, l,    0,    k,    r, r")
+	(plus:QIHISI (match_operand:QIHISI 1 "register_operand"      "%   0,    l,    0,    l,  0, l,    0,    k,    r, r")
 		     (match_operand:QIHISI 2 "nds32_rimm15s_operand" " In05, In03, Iu05, Iu03,  r, l, Is10, Iu06, Is15, r")))]
   ""
 {
@@ -382,9 +382,9 @@ (define_insn "*sub_srli"
 ;; Multiplication instructions.
 
 (define_insn "mulsi3"
-  [(set (match_operand:SI 0 "register_operand"          "= w, r")
-	(mult:SI (match_operand:SI 1 "register_operand" " %0, r")
-		 (match_operand:SI 2 "register_operand" "  w, r")))]
+  [(set (match_operand:SI 0 "register_operand"          "=w, r")
+	(mult:SI (match_operand:SI 1 "register_operand" "%0, r")
+		 (match_operand:SI 2 "register_operand" " w, r")))]
   ""
   "@
   mul33\t%0, %2
@@ -489,9 +489,9 @@ (define_insn "bitc"
 )
 
 (define_insn "andsi3"
-  [(set (match_operand:SI 0 "register_operand"         "= w, r,    l,    l,    l,    l,    l,    l,    r,   r,     r,    r,    r")
-	(and:SI (match_operand:SI 1 "register_operand" " %0, r,    l,    l,    l,    l,    0,    0,    r,   r,     r,    r,    r")
-		(match_operand:SI 2 "general_operand"  "  w, r, Izeb, Izeh, Ixls, Ix11, Ibms, Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
+  [(set (match_operand:SI 0 "register_operand"         "=w, r,    l,    l,    l,    l,    l,    l,    r,   r,     r,    r,    r")
+	(and:SI (match_operand:SI 1 "register_operand" "%0, r,    l,    l,    l,    l,    0,    0,    r,   r,     r,    r,    r")
+		(match_operand:SI 2 "general_operand"  " w, r, Izeb, Izeh, Ixls, Ix11, Ibms, Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
   ""
 {
   HOST_WIDE_INT mask = INTVAL (operands[2]);
@@ -585,9 +585,9 @@ (define_insn "*and_srli"
 ;; For V3/V3M ISA, we have 'or33' instruction.
 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
 (define_insn "iorsi3"
-  [(set (match_operand:SI 0 "register_operand"         "= w, r,    r,    r")
-	(ior:SI (match_operand:SI 1 "register_operand" " %0, r,    r,    r")
-		(match_operand:SI 2 "general_operand"  "  w, r, Iu15, Ie15")))]
+  [(set (match_operand:SI 0 "register_operand"         "=w, r,    r,    r")
+	(ior:SI (match_operand:SI 1 "register_operand" "%0, r,    r,    r")
+		(match_operand:SI 2 "general_operand"  " w, r, Iu15, Ie15")))]
   ""
 {
   int one_position;
@@ -645,9 +645,9 @@ (define_insn "*or_srli"
 ;; For V3/V3M ISA, we have 'xor33' instruction.
 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
 (define_insn "xorsi3"
-  [(set (match_operand:SI 0 "register_operand"         "= w, r,    r,    r")
-	(xor:SI (match_operand:SI 1 "register_operand" " %0, r,    r,    r")
-		(match_operand:SI 2 "general_operand"  "  w, r, Iu15, It15")))]
+  [(set (match_operand:SI 0 "register_operand"         "=w, r,    r,    r")
+	(xor:SI (match_operand:SI 1 "register_operand" "%0, r,    r,    r")
+		(match_operand:SI 2 "general_operand"  " w, r, Iu15, It15")))]
   ""
 {
   int one_position;
