aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorChristian Bruel <chrbr@gcc.gnu.org>2014-01-27 09:39:49 +0100
committerChristian Bruel <chrbr@gcc.gnu.org>2014-01-27 09:39:49 +0100
commit770516c9449f5f4cef53f3708810f018c0fdc6f0 (patch)
tree33100fc88a5ea7c0c6a84f0928ded1e8ecf8f552 /gcc
parentba3ca09806356ed27fd4fbd9f395c239034df342 (diff)
downloadgcc-770516c9449f5f4cef53f3708810f018c0fdc6f0.zip
gcc-770516c9449f5f4cef53f3708810f018c0fdc6f0.tar.gz
gcc-770516c9449f5f4cef53f3708810f018c0fdc6f0.tar.bz2
sh-mem.cc (sh_expand_cmpnstr): Fix remaining bytes after words comparisons.
2014-01-27 Christian Bruel <christian.bruel@st.com> * config/sh/sh-mem.cc (sh_expand_cmpnstr): Fix remaining bytes after words comparisons. From-SVN: r207126
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/sh/sh-mem.cc48
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/sh/torture/strncmp.c22
4 files changed, 71 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 226b721..7e50d07 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-01-27 Christian Bruel <christian.bruel@st.com>
+
+ * config/sh/sh-mem.cc (sh_expand_cmpnstr): Fix remaining bytes after
+ words comparisons.
+
2014-01-26 John David Anglin <danglin@gcc.gnu.org>
* config/pa/pa.md (call): Generate indirect long calls to non-local
@@ -17,9 +22,9 @@
2014-01-25 Walter Lee <walt@tilera.com>
- * config/tilegx/tilegx-c.c (tilegx_cpu_cpp_builtins):
+ * config/tilegx/tilegx-c.c (tilegx_cpu_cpp_builtins):
Define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_{1,2}.
- * config/tilegx/tilepro-c.c (tilepro_cpu_cpp_builtins):
+ * config/tilegx/tilepro-c.c (tilepro_cpu_cpp_builtins):
Define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_{1,2,4,8}.
2014-01-25 Walter Lee <walt@tilera.com>
@@ -46,7 +51,7 @@
* config/tilepro/tilepro.c (tilepro_expand_builtin): Ditto.
2014-01-25 Richard Sandiford <rdsandiford@googlemail.com>
-
+
* config/mips/constraints.md (kl): Delete.
* config/mips/mips.md (divmod<mode>4, udivmod<mode>4): Turn into
define expands, using...
diff --git a/gcc/config/sh/sh-mem.cc b/gcc/config/sh/sh-mem.cc
index e29ff77..45af23a 100644
--- a/gcc/config/sh/sh-mem.cc
+++ b/gcc/config/sh/sh-mem.cc
@@ -344,7 +344,6 @@ sh_expand_cmpnstr (rtx *operands)
rtx L_loop_long = gen_label_rtx ();
rtx L_end_loop_long = gen_label_rtx ();
- rtx L_small = gen_label_rtx ();
int align = INTVAL (operands[4]);
int bytes = INTVAL (operands[3]);
@@ -403,33 +402,59 @@ sh_expand_cmpnstr (rtx *operands)
jump = emit_jump_insn (gen_branch_false (L_loop_long));
add_int_reg_note (jump, REG_BR_PROB, prob_likely);
+ int sbytes = bytes % 4;
+
/* end loop. Reached max iterations. */
- if (bytes % 4 == 0)
+ if (! sbytes)
{
- /* Done. */
jump = emit_jump_insn (gen_jump_compact (L_return));
emit_barrier_after (jump);
}
else
{
- /* Remaining bytes to read. */
- jump = emit_jump_insn (gen_jump_compact (L_small));
+ /* Remaining bytes to check. */
+
+ addr1 = adjust_automodify_address (addr1, QImode, s1_addr, 0);
+ addr2 = adjust_automodify_address (addr2, QImode, s2_addr, 0);
+
+ while (sbytes--)
+ {
+ emit_insn (gen_extendqisi2 (tmp1, addr1));
+ emit_insn (gen_extendqisi2 (tmp2, addr2));
+
+ 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);
+
+ addr1 = adjust_address (addr1, QImode,
+ GET_MODE_SIZE (QImode));
+ addr2 = adjust_address (addr2, QImode,
+ GET_MODE_SIZE (QImode));
+ }
+
+ jump = emit_jump_insn (gen_jump_compact( L_end_loop_byte));
emit_barrier_after (jump);
}
emit_label (L_end_loop_long);
/* Found last word. Restart it byte per byte. */
- bytes = 4;
+
emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr,
-GET_MODE_SIZE (SImode)));
emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr,
-GET_MODE_SIZE (SImode)));
- }
- emit_label (L_small);
-
- gcc_assert (bytes <= 7);
+ /* fall thru. */
+ }
addr1 = adjust_automodify_address (addr1, QImode, s1_addr, 0);
addr2 = adjust_automodify_address (addr2, QImode, s2_addr, 0);
@@ -445,7 +470,8 @@ sh_expand_cmpnstr (rtx *operands)
emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
if (flag_delayed_branch)
- emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2)));
+ 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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9579219..fa61d5c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2014-01-27 Christian Bruel <christian.bruel@st.com>
+
+ * gcc.target/sh/torture/strncmp.c: New tests.
+
2014-01-25 Richard Sandiford <rdsandiford@googlemail.com>
* gcc.dg/unroll_1.c: Add -fenable-rtl-loop2.
diff --git a/gcc/testsuite/gcc.target/sh/torture/strncmp.c b/gcc/testsuite/gcc.target/sh/torture/strncmp.c
new file mode 100644
index 0000000..cd50f5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/torture/strncmp.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+const char *s="astc";
+const char *s1="-----BEGIN RSA PRIVATE KEY-----";
+const char *s2="atextaac";
+
+main()
+{
+ if (! __builtin_strncmp ("astb", s, 4))
+ abort();
+
+ if (__builtin_strncmp(s1, "-----BEGIN ", 11))
+ abort();
+
+ if (! __builtin_strncmp ("atextaacb", s2, 9))
+ abort();
+
+ return 0;
+}
+