long int longswap_(le_long)
long int le_long;
{
  union {
    long wl;
    unsigned short ws[2];
  } wsbuf;
  short shold;
  wsbuf.wl = le_long;
  shold = wsbuf.ws[0];
  wsbuf.ws[0] = wsbuf.ws[1];
  wsbuf.ws[1] = shold;
  wsbuf.ws[0] = shortswap_(wsbuf.ws[0]);
  wsbuf.ws[1] = shortswap_(wsbuf.ws[1]);
  return (wsbuf.wl);
}


x86 assembly (clang, -O0):
<longswap_>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%ax
mov    %ax,-0x12(%rbp)
mov    -0xe(%rbp),%ax
mov    %ax,-0x10(%rbp)
mov    -0x12(%rbp),%ax
mov    %ax,-0xe(%rbp)
movzwl -0x10(%rbp),%edi
mov    $0x0,%al
call   1030 <shortswap_@plt>
mov    %ax,-0x10(%rbp)
movzwl -0xe(%rbp),%edi
mov    $0x0,%al
call   1030 <shortswap_@plt>
mov    %ax,-0xe(%rbp)
mov    -0x10(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<longswap_>:
push   %rbp
push   %r14
push   %rbx
mov    %rdi,%rbx
shr    $0x10,%edi
movabs $0xffffffff00000000,%rbp
ff ff ff
and    %rbx,%rbp
xor    %eax,%eax
call   1030 <shortswap_@plt>
mov    %eax,%r14d
movzwl %bx,%edi
xor    %eax,%eax
call   1030 <shortswap_@plt>
shl    $0x10,%eax
movzwl %r14w,%ecx
or     %rbp,%rcx
or     %rcx,%rax
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
%union.anon = type { i64 }
define i64 @longswap_(i64 %0) {
%2 = alloca i64
%3 = alloca %union.anon
%4 = alloca i16
store i64 %0, i64* %2
%5 = load i64, i64* %2
%6 = bitcast %union.anon* %3 to i64*
store i64 %5, i64* %6
%7 = bitcast %union.anon* %3 to [2 x i16]*
%8 = getelementptr inbounds [2 x i16], [2 x i16]* %7, i64 0, i64 0
%9 = load i16, i16* %8
store i16 %9, i16* %4
%10 = bitcast %union.anon* %3 to [2 x i16]*
%11 = getelementptr inbounds [2 x i16], [2 x i16]* %10, i64 0, i64 1
%12 = load i16, i16* %11
%13 = bitcast %union.anon* %3 to [2 x i16]*
%14 = getelementptr inbounds [2 x i16], [2 x i16]* %13, i64 0, i64 0
store i16 %12, i16* %14
%15 = load i16, i16* %4
%16 = bitcast %union.anon* %3 to [2 x i16]*
%17 = getelementptr inbounds [2 x i16], [2 x i16]* %16, i64 0, i64 1
store i16 %15, i16* %17
%18 = bitcast %union.anon* %3 to [2 x i16]*
%19 = getelementptr inbounds [2 x i16], [2 x i16]* %18, i64 0, i64 0
%20 = load i16, i16* %19
%21 = zext i16 %20 to i32
%22 = call i32 (i32, ...) bitcast (i32 (...)* @shortswap_ to i32 (i32, ...)*)(i32 %21)
%23 = trunc i32 %22 to i16
%24 = bitcast %union.anon* %3 to [2 x i16]*
%25 = getelementptr inbounds [2 x i16], [2 x i16]* %24, i64 0, i64 0
store i16 %23, i16* %25
%26 = bitcast %union.anon* %3 to [2 x i16]*
%27 = getelementptr inbounds [2 x i16], [2 x i16]* %26, i64 0, i64 1
%28 = load i16, i16* %27
%29 = zext i16 %28 to i32
%30 = call i32 (i32, ...) bitcast (i32 (...)* @shortswap_ to i32 (i32, ...)*)(i32 %29)
%31 = trunc i32 %30 to i16
%32 = bitcast %union.anon* %3 to [2 x i16]*
%33 = getelementptr inbounds [2 x i16], [2 x i16]* %32, i64 0, i64 1
store i16 %31, i16* %33
%34 = bitcast %union.anon* %3 to i64*
%35 = load i64, i64* %34
ret i64 %35
}

LLVM IR (-O2):
define i64 @longswap_(i64 %0) {
%2 = trunc i64 %0 to i32
%3 = lshr i32 %2, 16
%4 = and i64 %0, -4294967296
%5 = tail call i32 (i32, ...) bitcast (i32 (...)* @shortswap_ to i32 (i32, ...)*)(i32 %3)
%6 = and i32 %2, 65535
%7 = tail call i32 (i32, ...) bitcast (i32 (...)* @shortswap_ to i32 (i32, ...)*)(i32 %6)
%8 = shl i32 %7, 16
%9 = zext i32 %8 to i64
%10 = and i32 %5, 65535
%11 = zext i32 %10 to i64
%12 = or i64 %4, %11
%13 = or i64 %12, %9
ret i64 %13
}