[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



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



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.