|
[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 2:39:51 PM PDT, David Laight
<david.laight.linux@xxxxxxxxx> wrote:
>On Wed, 09 Sep 2026 12:33:40 -0700
>"H. Peter Anvin" <hpa@xxxxxxxxx> wrote:
>
>> 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.
>
>And, of course, I knew that.
>They also zero the high 24bits of the registers.
>Given the setup cost of 'repe cmpsb' I suspect the xor just add code
>bytes.
>
>David
>
>
The XOR is cheaper than the sign extend; look at the object code.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |