builtins.c (expand_builtin_memcmp): Do not use cmpstrnsi pattern.
* 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. From-SVN: r177701
This commit is contained in:
parent
c49b1a299e
commit
9b0f6f5e51
3 changed files with 29 additions and 27 deletions
|
@ -1,3 +1,13 @@
|
|||
2011-08-12 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* 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 <ubizjak@gmail.com>
|
||||
|
||||
* builtins.def (BUILT_IN_ICEIL{,F,L}, BUILT_IN_IFLOOR{,F,L}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Add table
Reference in a new issue