long unload_16_bit(char *data, int *i, int swap) {
  long h, rval;
  long l;
  if (swap) {
    l = *(data + *i) & 0x00FF;
    h = *(data + *i + 1) << 8;
  } else {
    l = *(data + *i + 1) & 0x00FF;
    h = *(data + *i) << 8;
  }
  *i += 2;
  rval = (h + l) & 0xFFFF;
  return rval;
}


x86 assembly (clang, -O0):
<unload_16_bit>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
je     1151 <unload_16_bit+0x51>
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
movslq (%rcx),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xff,%eax
cltq
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
movslq (%rcx),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
shl    $0x8,%eax
cltq
mov    %rax,-0x20(%rbp)
jmp    1184 <unload_16_bit+0x84>
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
movslq (%rcx),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
and    $0xff,%eax
cltq
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
movslq (%rcx),%rcx
movsbl (%rax,%rcx,1),%eax
shl    $0x8,%eax
cltq
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%ecx
add    $0x2,%ecx
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
add    -0x30(%rbp),%rax
and    $0xffff,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<unload_16_bit>:
movslq (%rsi),%rax
lea    (%rdi,%rax,1),%rcx
test   %edx,%edx
lea    0x1(%rdi,%rax,1),%rdx
mov    %rdx,%rdi
cmove  %rcx,%rdi
cmovne %rcx,%rdx
movzbl (%rdx),%ecx
movzbl (%rdi),%edx
shl    $0x8,%edx
add    $0x2,%eax
mov    %eax,(%rsi)
movzwl %dx,%eax
or     %rcx,%rax
ret

LLVM IR (-O0):
define i64 @unload_16_bit(i8* %0, i32* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i32*
%6 = alloca i32
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
store i8* %0, i8** %4
store i32* %1, i32** %5
store i32 %2, i32* %6
%10 = load i32, i32* %6
%11 = icmp ne i32 %10, 0
br i1 %11, label %12, label %32
12: ; preds = %3
%13 = load i8*, i8** %4
%14 = load i32*, i32** %5
%15 = load i32, i32* %14
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds i8, i8* %13, i64 %16
%18 = load i8, i8* %17
%19 = sext i8 %18 to i32
%20 = and i32 %19, 255
%21 = sext i32 %20 to i64
store i64 %21, i64* %9
%22 = load i8*, i8** %4
%23 = load i32*, i32** %5
%24 = load i32, i32* %23
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds i8, i8* %22, i64 %25
%27 = getelementptr inbounds i8, i8* %26, i64 1
%28 = load i8, i8* %27
%29 = sext i8 %28 to i32
%30 = shl i32 %29, 8
%31 = sext i32 %30 to i64
store i64 %31, i64* %7
br label %52
32: ; preds = %3
%33 = load i8*, i8** %4
%34 = load i32*, i32** %5
%35 = load i32, i32* %34
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds i8, i8* %33, i64 %36
%38 = getelementptr inbounds i8, i8* %37, i64 1
%39 = load i8, i8* %38
%40 = sext i8 %39 to i32
%41 = and i32 %40, 255
%42 = sext i32 %41 to i64
store i64 %42, i64* %9
%43 = load i8*, i8** %4
%44 = load i32*, i32** %5
%45 = load i32, i32* %44
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds i8, i8* %43, i64 %46
%48 = load i8, i8* %47
%49 = sext i8 %48 to i32
%50 = shl i32 %49, 8
%51 = sext i32 %50 to i64
store i64 %51, i64* %7
br label %52
52: ; preds = %32, %12
%53 = load i32*, i32** %5
%54 = load i32, i32* %53
%55 = add nsw i32 %54, 2
store i32 %55, i32* %53
%56 = load i64, i64* %7
%57 = load i64, i64* %9
%58 = add nsw i64 %56, %57
%59 = and i64 %58, 65535
store i64 %59, i64* %8
%60 = load i64, i64* %8
ret i64 %60
}

LLVM IR (-O2):
define i64 @unload_16_bit(i8* nocapture %0, i32* nocapture %1, i32 %2) {
%4 = icmp eq i32 %2, 0
%5 = load i32, i32* %1
%6 = sext i32 %5 to i64
%7 = getelementptr inbounds i8, i8* %0, i64 %6
%8 = getelementptr inbounds i8, i8* %7, i64 1
%9 = select i1 %4, i8* %7, i8* %8
%10 = select i1 %4, i8* %8, i8* %7
%11 = load i8, i8* %10
%12 = zext i8 %11 to i64
%13 = load i8, i8* %9
%14 = sext i8 %13 to i64
%15 = shl nsw i64 %14, 8
%16 = add nsw i32 %5, 2
store i32 %16, i32* %1
%17 = and i64 %15, 65280
%18 = or i64 %17, %12
ret i64 %18
}