Re: [PATCH v9 2/5] x86/asm, x86/boot: expose inline memcmp()
From: David Laight
Date: Wed Sep 09 2026 - 17:54:21 EST
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