diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5698e9689ce..de9fb5e66c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-08-12 Nick Clifton + + * builtins.c (expand_builtin_memcmp): Do not use cmpstrnsi + pattern. + * doc/md.texi (cmpstrn): Note that the comparison stops if both + fetched bytes are zero. + (cmpstr): Likewise. + (cmpmem): Note that the comparison does not stop if both of the + fetched bytes are zero. + 2011-08-12 Uros Bizjak * builtins.def (BUILT_IN_ICEIL{,F,L}, BUILT_IN_IFLOOR{,F,L} diff --git a/gcc/builtins.c b/gcc/builtins.c index fec93221faa..e0afc908d5a 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -3635,9 +3635,9 @@ expand_builtin_bzero (tree exp) } /* Expand expression EXP, which is a call to the memcmp built-in function. - Return NULL_RTX if we failed and the - caller should emit a normal call, otherwise try to get the result in - TARGET, if convenient (and in mode MODE, if that's convenient). */ + Return NULL_RTX if we failed and the caller should emit a normal call, + otherwise try to get the result in TARGET, if convenient (and in mode + MODE, if that's convenient). */ static rtx expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, @@ -3649,7 +3649,10 @@ expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) return NULL_RTX; -#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi + /* Note: The cmpstrnsi pattern, if it exists, is not suitable for + implementing memcmp because it will stop if it encounters two + zero bytes. */ +#if defined HAVE_cmpmemsi { rtx arg1_rtx, arg2_rtx, arg3_rtx; rtx result; @@ -3662,16 +3665,9 @@ expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; 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_cmpstrnsi - if (HAVE_cmpstrnsi) - insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode; - else -#endif return NULL_RTX; /* If we don't have POINTER_TYPE, call the function. */ @@ -3696,18 +3692,10 @@ expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, set_mem_size (arg2_rtx, INTVAL (arg3_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_cmpstrnsi - if (HAVE_cmpstrnsi) - insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx, - GEN_INT (MIN (arg1_align, arg2_align))); - else -#endif gcc_unreachable (); if (insn) @@ -3733,7 +3721,7 @@ expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, else return convert_to_mode (mode, result, 0); } -#endif +#endif /* HAVE_cmpmemsi. */ return NULL_RTX; } diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 49dfda9db6c..0bd9ecdd167 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -4680,8 +4680,9 @@ byte by byte in lexicographic order starting at the beginning of each string. The instruction is not allowed to prefetch more than one byte at a time since either string may end in the first byte and reading past that may access an invalid page or segment and cause a fault. The -effect of the instruction is to store a value in operand 0 whose sign -indicates the result of the comparison. +comparison terminates early if the fetched bytes are different or if +they are equal to zero. The effect of the instruction is to store a +value in operand 0 whose sign indicates the result of the comparison. @cindex @code{cmpstr@var{m}} instruction pattern @item @samp{cmpstr@var{m}} @@ -4699,8 +4700,10 @@ The two memory blocks specified are compared byte by byte in lexicographic order starting at the beginning of each string. The instruction is not allowed to prefetch more than one byte at a time since either string may end in the first byte and reading past that may access an invalid page or segment and -cause a fault. The effect of the instruction is to store a value in operand 0 -whose sign indicates the result of the comparison. +cause a fault. The comparison will terminate when the fetched bytes +are different or if they are equal to zero. 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}} @@ -4708,9 +4711,10 @@ 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. +any bytes in the two memory blocks. Also unlike @samp{cmpstr@var{m}} +the comparison will not stop if both bytes are zero. 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}}