<div dir="ltr">bswapdi2 for i386 is correct<div><br></div><div>Bits 31:0 of the source are loaded into edx. Bits 63:32 are loaded into eax. Those are each bswapped. The ABI for the return is edx contains bits [63:32] and eax contains [31:0]. This is opposite of how the register were loaded.</div><div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">~Craig</div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Sun, Nov 25, 2018 at 10:36 AM Craig Topper <<a href="mailto:craig.topper@gmail.com">craig.topper@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">bswapsi2 on the x86-64 isn't using the bswap instruction because "unsigned long" is 64-bits on x86-64 linux. But its 32-bits on x86-64 msvc.<div><br></div><div>Not sure about the bswapdi2 i386 case.<br><div><br></div><div><br><div><div><div dir="ltr" class="m_-5035767654938968190gmail_signature" data-smartmail="gmail_signature">~Craig</div></div><br></div></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Sun, Nov 25, 2018 at 8:03 AM Stefan Kanthak via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi @ll,<br>
<br>
targetting i386, LLVM/clang generates wrong code for the following<br>
functions:<br>
<br>
unsigned long __bswapsi2 (unsigned long ul)<br>
{<br>
    return (((ul) & 0xff000000ul) >> 3 * 8)<br>
         | (((ul) & 0x00ff0000ul) >>     8)<br>
         | (((ul) & 0x0000ff00ul) <<     8)<br>
         | (((ul) & 0x000000fful) << 3 * 8);<br>
}<br>
<br>
unsigned long long __bswapdi2(unsigned long long ull)<br>
{<br>
    return ((ull & 0xff00000000000000ull) >> 7 * 8)<br>
         | ((ull & 0x00ff000000000000ull) >> 5 * 8)<br>
         | ((ull & 0x0000ff0000000000ull) >> 3 * 8)<br>
         | ((ull & 0x000000ff00000000ull) >>     8)<br>
         | ((ull & 0x00000000ff000000ull) <<     8)<br>
         | ((ull & 0x0000000000ff0000ull) << 3 * 8)<br>
         | ((ull & 0x000000000000ff00ull) << 5 * 8)<br>
         | ((ull & 0x00000000000000ffull) << 7 * 8);<br>
}<br>
<br>
You can find these sources in "compiler-rt/lib/builtins/bswapsi2.c"<br>
and "compiler-rt/lib/builtins/bswapdi2.c", for example!<br>
<br>
<br>
Compiled with "-O3 -target i386" this yields the following code<br>
(see <<a href="https://godbolt.org/z/F4UIl4" rel="noreferrer" target="_blank">https://godbolt.org/z/F4UIl4</a>>):<br>
<br>
__bswapsi2: # @__bswapsi2<br>
    push  ebp<br>
    mov   ebp, esp<br>
    mov   eax, dword ptr [ebp + 8]<br>
    bswap eax<br>
    pop   ebp<br>
    ret<br>
<br>
__bswapdi2: # @__bswapdi2<br>
    push  ebp<br>
    mov   ebp, esp<br>
    mov   edx, dword ptr [ebp + 8]<br>
    mov   eax, dword ptr [ebp + 12]<br>
    bswap eax<br>
    bswap edx<br>
    pop   ebp<br>
    ret<br>
<br>
__bswapsi2() is correct, but __bswapdi2() NOT: swapping just the<br>
halves of a "long long" is OBVIOUSLY WRONG!<br>
<br>
>From the C source, the expected result for the input value<br>
0x0123456789ABCDEF is 0xEFCDAB8967452301; the compiled code but<br>
produces 0x67452301EFCDAB89<br>
<br>
<br>
And compiled for x86-64 this yields the following code (see<br>
<<a href="https://godbolt.org/z/uM9nvN" rel="noreferrer" target="_blank">https://godbolt.org/z/uM9nvN</a>>):<br>
<br>
__bswapsi2: # @__bswapsi2<br>
    mov   eax, edi<br>
    shr   eax, 24<br>
    mov   rcx, rdi<br>
    shr   rcx, 8<br>
    and   ecx, 65280<br>
    or    rax, rcx<br>
    mov   rcx, rdi<br>
    shl   rcx, 8<br>
    and   ecx, 16711680<br>
    or    rax, rcx<br>
    and   rdi, 255<br>
    shl   rdi, 24<br>
    or    rax, rdi<br>
    ret<br>
<br>
__bswapdi2: # @__bswapdi2<br>
    bswap rdi<br>
    mov   rax, rdi<br>
    ret<br>
<br>
Both are correct, but __bswapsi2() should of course use BSWAP too!<br>
<br>
<br>
Stefan Kanthak<br>
<br>
PS: for comparision with another compiler, take a look at<br>
    <<a href="https://skanthak.homepage.t-online.de/msvc.html#example5" rel="noreferrer" target="_blank">https://skanthak.homepage.t-online.de/msvc.html#example5</a>><br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>
</blockquote></div>