From 15d0c620b0d23f18b0f44b8a14f0ad5006275e6d Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 3 Aug 2004 20:06:58 +0000 Subject: [PATCH] backport: optabs.c (prepare_cmp_insn): Try cmpmemM first if it exists, then fall back to cmpstrM. Backport from mainline: 2003-07-11 Jakub Jelinek * optabs.c (prepare_cmp_insn): Try cmpmemM first if it exists, then fall back to cmpstrM. * builtins.c (expand_builtin_memcmp): Likewise. * config/s390/s390-protos.h (s390_expand_cmpstr): Rename to... (s390_expand_cmpmem): ... this. * config/s390/s390.md (cmpmemdi, cmpmemsi, cmpmem_short_64, cmpmem_short_31, cmpmem_long_64, cmpmem_long_31): Renamed from cmpstr* patterns. Rename call to s390_expand_cmpstr to s390_expand_cmpmem. * config/s390/s390.c (s390_expand_cmpstr): Rename to... (s390_expand_cmpstr): ... this. Rename cmpstr* instructions to cmpmem*. * config/i370/i370.md (cmpmemsi, cmpmemsi_1): Renamed from cmpstr* patterns. * doc/md.texi (cmpstrM): Describe as String compare insn, not Block compare insn. (cmpmemM): Add. * gcc.dg/20030711-1.c: New test. From-SVN: r85497 --- gcc/ChangeLog | 22 ++++++++++++++++++++++ gcc/builtins.c | 29 ++++++++++++++++++++++++----- gcc/config/i370/i370.md | 8 ++++---- gcc/config/s390/s390-protos.h | 2 +- gcc/config/s390/s390.c | 6 +++--- gcc/config/s390/s390.md | 18 +++++++++--------- gcc/doc/md.texi | 12 +++++++++++- gcc/optabs.c | 34 ++++++++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 6 ++++++ 9 files changed, 114 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6b065c4d1d87..d2088262f4b2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2004-08-02 Ulrich Weigand + + Backport from mainline: + 2003-07-11 Jakub Jelinek + * optabs.c (prepare_cmp_insn): Try cmpmemM first if it exists, + then fall back to cmpstrM. + * builtins.c (expand_builtin_memcmp): Likewise. + * config/s390/s390-protos.h (s390_expand_cmpstr): Rename to... + (s390_expand_cmpmem): ... this. + * config/s390/s390.md (cmpmemdi, cmpmemsi, cmpmem_short_64, + cmpmem_short_31, cmpmem_long_64, cmpmem_long_31): Renamed + from cmpstr* patterns. Rename call to s390_expand_cmpstr + to s390_expand_cmpmem. + * config/s390/s390.c (s390_expand_cmpstr): Rename to... + (s390_expand_cmpstr): ... this. Rename cmpstr* instructions + to cmpmem*. + * config/i370/i370.md (cmpmemsi, cmpmemsi_1): Renamed from + cmpstr* patterns. + * doc/md.texi (cmpstrM): Describe as String compare insn, not + Block compare insn. + (cmpmemM): Add. + 2004-07-25 Andreas Jaeger Backport from mainline: diff --git a/gcc/builtins.c b/gcc/builtins.c index 55ef544d3f54..bfc7e4065edf 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2418,7 +2418,7 @@ expand_builtin_memcmp (exp, arglist, target, mode) return expand_expr (result, target, mode, EXPAND_NORMAL); } -#ifdef HAVE_cmpstrsi +#if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi { rtx arg1_rtx, arg2_rtx, arg3_rtx; rtx result; @@ -2428,8 +2428,19 @@ expand_builtin_memcmp (exp, arglist, target, mode) = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; int arg2_align = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; - enum machine_mode insn_mode - = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode; + enum machine_mode insn_mode; + +#ifdef HAVE_cmpmemsi + if (HAVE_cmpmemsi) + insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode; + else +#endif +#ifdef HAVE_cmpstrsi + if (HAVE_cmpstrsi) + insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode; + else +#endif + return 0; /* If we don't have POINTER_TYPE, call the function. */ if (arg1_align == 0 || arg2_align == 0) @@ -2445,11 +2456,19 @@ expand_builtin_memcmp (exp, arglist, target, mode) arg1_rtx = get_memory_rtx (arg1); arg2_rtx = get_memory_rtx (arg2); arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); - if (!HAVE_cmpstrsi) - insn = NULL_RTX; +#ifdef HAVE_cmpmemsi + if (HAVE_cmpmemsi) + insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx, + GEN_INT (MIN (arg1_align, arg2_align))); else +#endif +#ifdef HAVE_cmpstrsi + if (HAVE_cmpstrsi) insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx, GEN_INT (MIN (arg1_align, arg2_align))); + else +#endif + abort (); if (insn) emit_insn (insn); diff --git a/gcc/config/i370/i370.md b/gcc/config/i370/i370.md index 9564cb3001eb..26ca0f3d5133 100644 --- a/gcc/config/i370/i370.md +++ b/gcc/config/i370/i370.md @@ -474,10 +474,10 @@ check_label_emit (); ) ; -; cmpstrsi instruction pattern(s). +; cmpmemsi instruction pattern(s). ; -(define_expand "cmpstrsi" +(define_expand "cmpmemsi" [(set (match_operand:SI 0 "general_operand" "") (compare (match_operand:BLK 1 "general_operand" "") (match_operand:BLK 2 "general_operand" ""))) @@ -545,7 +545,7 @@ check_label_emit (); emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE (SImode)), len); /* Compare! */ - emit_insn (gen_cmpstrsi_1 (result, reg1, reg2)); + emit_insn (gen_cmpmemsi_1 (result, reg1, reg2)); } DONE; }") @@ -569,7 +569,7 @@ check_label_emit (); ; Compare a block that is larger than 255 bytes in length. -(define_insn "cmpstrsi_1" +(define_insn "cmpmemsi_1" [(set (match_operand:SI 0 "register_operand" "+d") (compare (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 0)) diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index ab4835242885..f11adc23878e 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -69,7 +69,7 @@ extern void emit_symbolic_move PARAMS ((rtx *)); extern void s390_load_address PARAMS ((rtx, rtx)); extern void s390_expand_movstr PARAMS ((rtx, rtx, rtx)); extern void s390_expand_clrstr PARAMS ((rtx, rtx)); -extern void s390_expand_cmpstr PARAMS ((rtx, rtx, rtx, rtx)); +extern void s390_expand_cmpmem PARAMS ((rtx, rtx, rtx, rtx)); extern rtx s390_return_addr_rtx PARAMS ((int, rtx)); extern void s390_output_symbolic_const PARAMS ((FILE *, rtx)); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 28f4f9630aa4..6ef79c92fc3b 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2830,16 +2830,16 @@ s390_expand_clrstr (dst, len) and return the result in TARGET. */ void -s390_expand_cmpstr (target, op0, op1, len) +s390_expand_cmpmem (target, op0, op1, len) rtx target; rtx op0; rtx op1; rtx len; { rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) = - TARGET_64BIT ? gen_cmpstr_short_64 : gen_cmpstr_short_31; + TARGET_64BIT ? gen_cmpmem_short_64 : gen_cmpmem_short_31; rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) = - TARGET_64BIT ? gen_cmpstr_long_64 : gen_cmpstr_long_31; + TARGET_64BIT ? gen_cmpmem_long_64 : gen_cmpmem_long_31; rtx (*gen_result) PARAMS ((rtx)) = GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si; diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 0ad76dc00d68..1fb80c9aa457 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1863,33 +1863,33 @@ (set_attr "length" "8")]) ; -; cmpstrM instruction pattern(s). +; cmpmemM instruction pattern(s). ; -(define_expand "cmpstrdi" +(define_expand "cmpmemdi" [(set (match_operand:DI 0 "register_operand" "") (compare:DI (match_operand:BLK 1 "memory_operand" "") (match_operand:BLK 2 "memory_operand" "") ) ) (use (match_operand:DI 3 "general_operand" "")) (use (match_operand:DI 4 "" ""))] "TARGET_64BIT" - "s390_expand_cmpstr (operands[0], operands[1], + "s390_expand_cmpmem (operands[0], operands[1], operands[2], operands[3]); DONE;") -(define_expand "cmpstrsi" +(define_expand "cmpmemsi" [(set (match_operand:SI 0 "register_operand" "") (compare:SI (match_operand:BLK 1 "memory_operand" "") (match_operand:BLK 2 "memory_operand" "") ) ) (use (match_operand:SI 3 "general_operand" "")) (use (match_operand:SI 4 "" ""))] "" - "s390_expand_cmpstr (operands[0], operands[1], + "s390_expand_cmpmem (operands[0], operands[1], operands[2], operands[3]); DONE;") ; Compare a block that is up to 256 bytes in length. ; The block length is taken as (operands[2] % 256) + 1. -(define_insn "cmpstr_short_64" +(define_insn "cmpmem_short_64" [(set (reg:CCS 33) (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q") (match_operand:BLK 1 "memory_operand" "Q,Q"))) @@ -1917,7 +1917,7 @@ (set_attr "atype" "mem,mem") (set_attr "length" "*,14")]) -(define_insn "cmpstr_short_31" +(define_insn "cmpmem_short_31" [(set (reg:CCS 33) (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q") (match_operand:BLK 1 "memory_operand" "Q,Q"))) @@ -1947,7 +1947,7 @@ ; Compare a block of arbitrary length. -(define_insn "cmpstr_long_64" +(define_insn "cmpmem_long_64" [(clobber (match_operand:TI 0 "register_operand" "=d")) (clobber (match_operand:TI 1 "register_operand" "=d")) (set (reg:CCS 33) @@ -1962,7 +1962,7 @@ (set_attr "type" "vs") (set_attr "length" "8")]) -(define_insn "cmpstr_long_31" +(define_insn "cmpmem_long_31" [(clobber (match_operand:DI 0 "register_operand" "=d")) (clobber (match_operand:DI 1 "register_operand" "=d")) (set (reg:CCS 33) diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 822ec14998f9..4047284f0820 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -2709,13 +2709,23 @@ The use for multiple @code{clrstr@var{m}} is as for @code{movstr@var{m}}. @cindex @code{cmpstr@var{m}} instruction pattern @item @samp{cmpstr@var{m}} -Block compare instruction, with five operands. Operand 0 is the output; +String compare instruction, with five operands. Operand 0 is the output; it has mode @var{m}. The remaining four operands are like the operands of @samp{movstr@var{m}}. The two memory blocks specified are compared byte by byte in lexicographic order. The effect of the instruction is to store a value in operand 0 whose sign indicates the result of the comparison. +@cindex @code{cmpmem@var{m}} instruction pattern +@item @samp{cmpmem@var{m}} +Block compare instruction, with five operands like the operands +of @samp{cmpstr@var{m}}. The two memory blocks specified are compared +byte by byte in lexicographic order starting at the beginning of each +block. Unlike @samp{cmpstr@var{m}} the instruction can prefetch +any bytes in the two memory blocks. The effect of the instruction is +to store a value in operand 0 whose sign indicates the result of the +comparison. + @cindex @code{strlen@var{m}} instruction pattern @item @samp{strlen@var{m}} Compute the length of a string, with three operands. diff --git a/gcc/optabs.c b/gcc/optabs.c index 9da601c4f84d..337ec6900919 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3416,6 +3416,40 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose) if (size == 0) abort (); +#ifdef HAVE_cmpmemqi + if (HAVE_cmpmemqi + && GET_CODE (size) == CONST_INT + && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode))) + { + result_mode = insn_data[(int) CODE_FOR_cmpmemqi].operand[0].mode; + result = gen_reg_rtx (result_mode); + emit_insn (gen_cmpmemqi (result, x, y, size, opalign)); + } + else +#endif +#ifdef HAVE_cmpmemhi + if (HAVE_cmpmemhi + && GET_CODE (size) == CONST_INT + && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode))) + { + result_mode = insn_data[(int) CODE_FOR_cmpmemhi].operand[0].mode; + result = gen_reg_rtx (result_mode); + emit_insn (gen_cmpmemhi (result, x, y, size, opalign)); + } + else +#endif +#ifdef HAVE_cmpmemsi + if (HAVE_cmpmemsi) + { + result_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode; + result = gen_reg_rtx (result_mode); + size = protect_from_queue (size, 0); + emit_insn (gen_cmpmemsi (result, x, y, + convert_to_mode (SImode, size, 1), + opalign)); + } + else +#endif #ifdef HAVE_cmpstrqi if (HAVE_cmpstrqi && GET_CODE (size) == CONST_INT diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b810bf99057e..12fb3d6834ce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2004-08-04 Ulrich Weigand + + Backport from mainline: + 2003-07-11 Jakub Jelinek + * gcc.dg/20030711-1.c: New test. + 2004-07-24 Kriang Lerdsuwanakij PR c++/16175 -- 2.47.2