From: Christian Bruel Date: Mon, 27 Jan 2014 08:39:49 +0000 (+0100) Subject: sh-mem.cc (sh_expand_cmpnstr): Fix remaining bytes after words comparisons. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=770516c9449f5f4cef53f3708810f018c0fdc6f0;p=gcc.git sh-mem.cc (sh_expand_cmpnstr): Fix remaining bytes after words comparisons. 2014-01-27 Christian Bruel * config/sh/sh-mem.cc (sh_expand_cmpnstr): Fix remaining bytes after words comparisons. From-SVN: r207126 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 226b721b4ce..7e50d078516 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-01-27 Christian Bruel + + * config/sh/sh-mem.cc (sh_expand_cmpnstr): Fix remaining bytes after + words comparisons. + 2014-01-26 John David Anglin * config/pa/pa.md (call): Generate indirect long calls to non-local @@ -17,9 +22,9 @@ 2014-01-25 Walter Lee - * 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 @@ -46,7 +51,7 @@ * config/tilepro/tilepro.c (tilepro_expand_builtin): Ditto. 2014-01-25 Richard Sandiford - + * config/mips/constraints.md (kl): Delete. * config/mips/mips.md (divmod4, udivmod4): Turn into define expands, using... diff --git a/gcc/config/sh/sh-mem.cc b/gcc/config/sh/sh-mem.cc index e29ff775449..45af23acb48 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 957921914e9..fa61d5c9874 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-01-27 Christian Bruel + + * gcc.target/sh/torture/strncmp.c: New tests. + 2014-01-25 Richard Sandiford * 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 00000000000..cd50f5c05a7 --- /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; +} +