Re: [PATCH v9 2/5] x86/asm, x86/boot: expose inline memcmp()

From: David Laight

Date: Wed Sep 09 2026 - 16:07:11 EST


On Wed, 9 Sep 2026 06:43:01 -0700
"H. Peter Anvin" <hpa@xxxxxxxxx> wrote:

> On 2026-09-09 01:38, David Laight wrote:
> >>
> >> Here is an out-of-line compact memcmp() which works for both 16/32 and 64 bits:
> >>
> <broken code removed>
>
> >>
> >> On 64 bits it compiles to:
> >>
> >> 0000000000000000 <memcmp>:
> >> 0: 48 89 d1 mov %rdx,%rcx
> >> 3: 31 d2 xor %edx,%edx
> >> 5: 31 c0 xor %eax,%eax
> >> 7: f3 a6 repz cmpsb (%rdi),(%rsi)
> >> 9: 0f 97 c2 seta %dl
> >> c: 0f 92 c0 setb %al
> >> f: 29 d0 sub %edx,%eax
> >
> > That isn't the object code from the source ...
> >
> And that's the ultimate hint that a cut and paste error had happened.
>
> This was the actual source code.
>
> int memcmp(const void *s1, const void *s2, size_t len)
> {
> int lt, gt;
>
> /*
> * Note: for the benefit of 64-bit code, xDI and xSI are reversed
> * compared with what CMPSB uses; hence SETA and SETB are also reversed.
> *
> * The XOR statements set ZF = 1, CF = 0, which is required to handle
> * the case len == 0 correctly.
> */
> asm volatile("xor %[lt],%[lt] ; "
> "xor %[gt],%[gt] ; "
> "repe cmpsb ; "
> "seta %b[lt] ; "
> "setb %b[gt]"
> : "+D" (s1), "+S" (s2), "+c" (len),
> [lt] "=&q" (lt), [gt] "=&q" (gt)
> : : "cc", "memory");
> return gt - lt;
> }
>

Try:

int memcmp_2(const void *s1, const void *s2, unsigned long len)
{
signed char lt, gt;

asm volatile("repe cmpsb ; "
"seta %[lt] ; "
"setb %[gt]"
: "+D" (s1), "+S" (s2), "+c" (len),
[lt] "=&q" (lt), [gt] "=&q" (gt)
: : "cc", "memory");
return (signed char)(gt - lt);
}

https://www.godbolt.org/z/6hrxGxb18

Saves the XORs - go away completely in the usual case of 'if (memcpy(....))'.
The 'mess' on the return statement moves the sign extend after the
subtract.

David