[Bug target/95151] New: Add cmpmemM pattern for -minline-all-stringops
hjl.tools at gmail dot com
gcc-bugzilla@gcc.gnu.org
Fri May 15 12:32:10 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95151
Bug ID: 95151
Summary: Add cmpmemM pattern for -minline-all-stringops
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: hjl.tools at gmail dot com
CC: crazylht at gmail dot com
Target Milestone: ---
Target: i386,x86-64
'cmpmemM'
Block compare instruction, with five operands like the operands of
'cmpstrM'. The two memory blocks specified are compared byte by
byte in lexicographic order starting at the beginning of each
block. Unlike 'cmpstrM' the instruction can prefetch any bytes in
the two memory blocks. Also unlike 'cmpstrM' 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.
We should add
(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 3 "general_operand"))
(use (match_operand 4 "immediate_operand"))]
""
{
if (ix86_expand_cmpmem (operands[0], operands[1], operands[2],
operands[3]))
DONE;
else
FAIL;
})
which can be expanded to sysdeps/i386/memcmp.S in glibc:
movl BLK1(%esp), %esi
cfi_rel_offset (esi, 0)
movl BLK2(%esp), %edi
movl LEN(%esp), %ecx
cld /* Set direction of comparison. */
xorl %eax, %eax /* Default result. */
repe /* Compare at most %ecx bytes. */
cmpsb
jz L(1) /* If even last byte was equal we return 0. */
/* The memory blocks are not equal. So result of the last
subtraction is present in the carry flag. It is set when
the byte in block #2 is bigger. In this case we have to
return -1 (=0xffffffff), else 1. */
sbbl %eax, %eax /* This is tricky. %eax == 0 and carry is set
or not depending on last subtraction. */
/* At this point %eax == 0, if the byte of block #1 was bigger, and
0xffffffff if the last byte of block #2 was bigger. The latter
case is already correct but the former needs a little adjustment.
Note that the following operation does not change 0xffffffff. */
orb $1, %al /* Change 0 to 1. */
L(1):
More information about the Gcc-bugs
mailing list