Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog	(revision 204346)
+++ gcc/ChangeLog	(working copy)
@@ -1,3 +1,9 @@
+2013-11-05  Christian Bruel  <christian.bruel@st.com>
+
+	* gcc/config/sh/sh-mem.cc (sh_expand_cmpnstr, sh_expand_cmpstr):
+	Factorize probabilities, Use adjust_address instead of
+	adjust_automodify_address when possible. Enable for optimize.
+
 2013-11-04  Richard Sandiford  <rdsandiford@googlemail.com>
 
 	* config/avr/avr-log.c (avr_double_int_pop_digit): Delete.
Index: gcc/config/sh/sh-mem.cc
===================================================================
--- gcc/config/sh/sh-mem.cc	(revision 204346)
+++ gcc/config/sh/sh-mem.cc	(working copy)
@@ -179,32 +179,31 @@ expand_block_move (rtx *operands)
   return false;
 }
 
+static int prob_unlikely = REG_BR_PROB_BASE / 10;
+static int prob_likely = REG_BR_PROB_BASE / 4;
+
 /* Emit code to perform a strcmp.
 
    OPERANDS[0] is the destination.
    OPERANDS[1] is the first string.
    OPERANDS[2] is the second string.
-   OPERANDS[3] is the align.  */
+   OPERANDS[3] is the known alignment.  */
 bool
 sh_expand_cmpstr (rtx *operands)
 {
-  rtx s1 = copy_rtx (operands[1]);
-  rtx s2 = copy_rtx (operands[2]);
-  rtx s1_addr = copy_addr_to_reg (XEXP (s1, 0));
-  rtx s2_addr = copy_addr_to_reg (XEXP (s2, 0));
+  rtx addr1 = operands[1];
+  rtx addr2 = operands[2];
+  rtx s1_addr = copy_addr_to_reg (XEXP (addr1, 0));
+  rtx s2_addr = copy_addr_to_reg (XEXP (addr2, 0));
   rtx tmp0 = gen_reg_rtx (SImode);
   rtx tmp1 = gen_reg_rtx (SImode);
   rtx tmp2 = gen_reg_rtx (SImode);
   rtx tmp3 = gen_reg_rtx (SImode);
 
+  rtx jump;
   rtx L_return = gen_label_rtx ();
   rtx L_loop_byte = gen_label_rtx ();
   rtx L_end_loop_byte = gen_label_rtx ();
-
-  rtx jump, addr1, addr2;
-  int prob_unlikely = REG_BR_PROB_BASE / 10;
-  int prob_likely = REG_BR_PROB_BASE / 4;
-
   rtx L_loop_long = gen_label_rtx ();
   rtx L_end_loop_long = gen_label_rtx ();
 
@@ -220,8 +219,8 @@ sh_expand_cmpstr (rtx *operands)
       add_int_reg_note (jump, REG_BR_PROB, prob_likely);
     }
 
-  addr1 = adjust_automodify_address (s1, SImode, s1_addr, 0);
-  addr2 = adjust_automodify_address (s2, SImode, s2_addr, 0);
+  addr1 = adjust_automodify_address (addr1, SImode, s1_addr, 0);
+  addr2 = adjust_automodify_address (addr2, SImode, s2_addr, 0);
 
   /* tmp2 is aligned, OK to load.  */
   emit_move_insn (tmp3, addr2);
@@ -276,8 +275,8 @@ sh_expand_cmpstr (rtx *operands)
   emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, -4));
 
   /* start byte loop.  */
-  addr1 = adjust_automodify_address (s1, QImode, s1_addr, 0);
-  addr2 = adjust_automodify_address (s2, QImode, s2_addr, 0);
+  addr1 = adjust_address (addr1, QImode, 0);
+  addr2 = adjust_address (addr2, QImode, 0);
 
   emit_label (L_loop_byte);
 
@@ -317,27 +316,23 @@ sh_expand_cmpstr (rtx *operands)
    OPERANDS[1] is the first string.
    OPERANDS[2] is the second string.
    OPERANDS[3] is the length.
-   OPERANDS[4] is the align.  */
+   OPERANDS[4] is the known alignment.  */
 bool
 sh_expand_cmpnstr (rtx *operands)
 {
-  rtx s1 = copy_rtx (operands[1]);
-  rtx s2 = copy_rtx (operands[2]);
-
-  rtx s1_addr = copy_addr_to_reg (XEXP (s1, 0));
-  rtx s2_addr = copy_addr_to_reg (XEXP (s2, 0));
+  rtx addr1 = operands[1];
+  rtx addr2 = operands[2];
+  rtx s1_addr = copy_addr_to_reg (XEXP (addr1, 0));
+  rtx s2_addr = copy_addr_to_reg (XEXP (addr2, 0));
   rtx tmp0 = gen_reg_rtx (SImode);
   rtx tmp1 = gen_reg_rtx (SImode);
   rtx tmp2 = gen_reg_rtx (SImode);
 
+  rtx jump;
   rtx L_return = gen_label_rtx ();
   rtx L_loop_byte = gen_label_rtx ();
   rtx L_end_loop_byte = gen_label_rtx ();
 
-  rtx jump, addr1, addr2;
-  int prob_unlikely = REG_BR_PROB_BASE / 10;
-  int prob_likely = REG_BR_PROB_BASE / 4;
-
   rtx len = force_reg (SImode, operands[3]);
   int constp = (CONST_INT_P (operands[3]));
   int bytes = (constp ? INTVAL (operands[3]) : 0);
@@ -366,10 +361,10 @@ sh_expand_cmpnstr (rtx *operands)
 	  add_int_reg_note (jump, REG_BR_PROB, prob_likely);
 	}
 
-      addr1 = adjust_automodify_address (s1, SImode, s1_addr, 0);
-      addr2 = adjust_automodify_address (s2, SImode, s2_addr, 0);
+      addr1 = adjust_automodify_address (addr1, SImode, s1_addr, 0);
+      addr2 = adjust_automodify_address (addr2, SImode, s2_addr, 0);
 
-      /* words count.  */
+      /* word count. Do we have iterations ? */
       emit_insn (gen_lshrsi3 (lenw, len, GEN_INT (2)));
 
       /*start long loop.  */
@@ -429,48 +424,48 @@ sh_expand_cmpnstr (rtx *operands)
       emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, -4));
     }
 
-    addr1 = adjust_automodify_address (s1, QImode, s1_addr, 0);
-    addr2 = adjust_automodify_address (s2, QImode, s2_addr, 0);
+  addr1 = adjust_address (addr1, QImode, 0);
+  addr2 = adjust_address (addr2, QImode, 0);
 
-    emit_label (L_loop_byte);
+  emit_label (L_loop_byte);
 
-    emit_insn (gen_extendqisi2 (tmp2, addr2));
-    emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, 1));
+  emit_insn (gen_extendqisi2 (tmp2, addr2));
+  emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, 1));
 
-    emit_insn (gen_extendqisi2 (tmp1, addr1));
-    emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr, 1));
+  emit_insn (gen_extendqisi2 (tmp1, addr1));
+  emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr, 1));
 
-    emit_insn (gen_cmpeqsi_t (tmp2, const0_rtx));
-    jump = emit_jump_insn (gen_branch_true (L_end_loop_byte));
-    add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+  emit_insn (gen_cmpeqsi_t (tmp2, const0_rtx));
+  jump = emit_jump_insn (gen_branch_true (L_end_loop_byte));
+  add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
 
-    emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
-    if (flag_delayed_branch)
-      emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2)));
-    jump = emit_jump_insn (gen_branch_false (L_end_loop_byte));
-    add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+  emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
+  if (flag_delayed_branch)
+    emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2)));
+  jump = emit_jump_insn (gen_branch_false (L_end_loop_byte));
+  add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
 
-    if (TARGET_SH2)
-      emit_insn (gen_dect (len, len));
-    else
-      {
-	emit_insn (gen_addsi3 (len, len, GEN_INT (-1)));
-	emit_insn (gen_tstsi_t (len, len));
-      }
+  if (TARGET_SH2)
+    emit_insn (gen_dect (len, len));
+  else
+    {
+      emit_insn (gen_addsi3 (len, len, GEN_INT (-1)));
+      emit_insn (gen_tstsi_t (len, len));
+    }
 
-    jump = emit_jump_insn (gen_branch_false (L_loop_byte));
-    add_int_reg_note (jump, REG_BR_PROB, prob_likely);
-    /* end byte loop.  */
+  jump = emit_jump_insn (gen_branch_false (L_loop_byte));
+  add_int_reg_note (jump, REG_BR_PROB, prob_likely);
+  /* end byte loop.  */
 
-    emit_label (L_end_loop_byte);
+  emit_label (L_end_loop_byte);
 
-    if (! flag_delayed_branch)
-      emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2)));
-    emit_insn (gen_zero_extendqisi2 (tmp1, gen_lowpart (QImode, tmp1)));
+  if (! flag_delayed_branch)
+    emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2)));
+  emit_insn (gen_zero_extendqisi2 (tmp1, gen_lowpart (QImode, tmp1)));
 
-    emit_label (L_return);
+  emit_label (L_return);
 
-    emit_insn (gen_subsi3 (operands[0], tmp1, tmp2));
+  emit_insn (gen_subsi3 (operands[0], tmp1, tmp2));
 
-    return true;
+  return true;
 }
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 204346)
+++ gcc/config/sh/sh.md	(working copy)
@@ -12059,7 +12059,7 @@ label:
 	(compare:SI (match_operand:BLK 1 "memory_operand")
 		    (match_operand:BLK 2 "memory_operand")))
    (use (match_operand 3 "immediate_operand"))]
-  "TARGET_SH1"
+  "TARGET_SH1 && optimize"
 {
   if (! optimize_insn_for_size_p () && sh_expand_cmpstr (operands))
     DONE;
@@ -12073,7 +12073,7 @@ label:
 		    (match_operand:BLK 2 "memory_operand")))
    (use (match_operand:SI 3 "immediate_operand"))
    (use (match_operand:SI 4 "immediate_operand"))]
-  "TARGET_SH1"
+  "TARGET_SH1 && optimize"
 {
   if (! optimize_insn_for_size_p () && sh_expand_cmpnstr (operands))
     DONE;
