[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 September 9, 2026 12:28:38 PM PDT, David Laight 
<david.laight.linux@xxxxxxxxx> wrote:
>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

The xors are explicitly in the asm to deal with the len = 0 case (this is for 
the out of line version!)

We need to enter with ZF = 1 CF = 0.



 


Rackspace

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