Re: [PATCH v7 2/5] x86/asm: add volatile, clobbers and zero-length check in inline memcmp
David Laight <[email protected]>
| Newsgroups | org.xenproject.lists.xen-devel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260725112734.2c65f37e@pumpkin> |
On Fri, 24 Jul 2026 17:25:21 -0700 "H. Peter Anvin" <[email protected]> wrote: > On 2026-07-24 16:57, H. Peter Anvin wrote: > > > > And of course I got the comparison backwards (negative means a < b, thus we > > want a - b not b - a). Here is a fixed version. > > > > int memcmp(const void *a, const void *b, size_t size) > > { > > int diff; > > > > asm volatile("xor %0,%0 ;" /* Sets ZF for the size = 0 case */ > > "repe cmpsb ;" > > "jz 1f ;" /* When size = 0 loading is unsafe */ > > "movb -1(%1),%b0 ;" > > "movzbl -1(%2),%k2 ;" > > "sub %k2,%0 ;" > > "1:" > > : "=&q" (diff), "+D" (a), "+S" (b), "+c" (size) > > : : "memory"); > > return diff; > > } > > > For extra credit, this version is even smaller in 16- and 32-bit mode, but > larger in 64-bit mode (because it depends on the order of the CMPSB operands, The function is inlined, so it will make no difference. David > which is the inverse of what the x86-64 ABI expects; swapping the order of "a" > and "b" and adding a cmc instruction improves the x86-64 size, but 64 bits is > not where the really tight code is...) > > int memcmp(const void *a, const void *b, size_t size) > { > int diff; > > asm volatile("xor %0,%0 ;" > "repe cmpsb ;" > "jz 1f ;" > "sbb %0,%0 ;" > "or $1,%0 ;" > "1:" > : "=&r" (diff), "+S" (a), "+D" (b), "+c" (size) > : : "memory"); > return diff; > } > >