#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ uint8_t;
typedef int uint16_t;

/* Variables and functions */
int ConvertFat12to16(uint8_t *dest, uint8_t *src, int maxentry) {
  uint8_t *p12 = src;
  uint16_t *p16 = (uint16_t *)dest;
  int i;
  for (i = 0; i < maxentry; i++) {
    if (i & 1) {
      *p16++ = (*(uint16_t *)p12 >> 4);
      p12 += 2;
    } else {
      *p16++ = (*(uint16_t *)p12 & 0xfff);
      p12++;
    }
  }
  return 0;
}


x86 assembly (clang, -O0):
<ConvertFat12to16>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    11a8 <ConvertFat12to16+0xa8>
mov    -0x2c(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     116c <ConvertFat12to16+0x6c>
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
sar    $0x4,%ecx
mov    -0x28(%rbp),%rax
mov    %rax,%rdx
add    $0x4,%rdx
mov    %rdx,-0x28(%rbp)
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x20(%rbp)
jmp    1195 <ConvertFat12to16+0x95>
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
and    $0xfff,%ecx
mov    -0x28(%rbp),%rax
mov    %rax,%rdx
add    $0x4,%rdx
mov    %rdx,-0x28(%rbp)
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x20(%rbp)
jmp    119a <ConvertFat12to16+0x9a>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1126 <ConvertFat12to16+0x26>
xor    %eax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ConvertFat12to16>:
test   %edx,%edx
jle    114b <ConvertFat12to16+0x4b>
cmp    $0x1,%edx
je     113d <ConvertFat12to16+0x3d>
mov    %edx,%eax
and    $0xfffffffe,%eax
mov    $0xfff,%r8d
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    (%rsi),%ecx
and    %r8d,%ecx
mov    %ecx,(%rdi)
mov    0x4(%rsi),%ecx
sar    $0x4,%ecx
mov    %ecx,0x4(%rdi)
add    $0xc,%rsi
add    $0x8,%rdi
add    $0xfffffffe,%eax
jne    1120 <ConvertFat12to16+0x20>
test   $0x1,%dl
je     114b <ConvertFat12to16+0x4b>
mov    $0xfff,%eax
and    (%rsi),%eax
mov    %eax,(%rdi)
xor    %eax,%eax
ret

LLVM IR (-O0):
define i32 @ConvertFat12to16(i32* %0, i32* %1, i32 %2) {
%4 = alloca i32*
%5 = alloca i32*
%6 = alloca i32
%7 = alloca i32*
%8 = alloca i32*
%9 = alloca i32
store i32* %0, i32** %4
store i32* %1, i32** %5
store i32 %2, i32* %6
%10 = load i32*, i32** %5
store i32* %10, i32** %7
%11 = load i32*, i32** %4
store i32* %11, i32** %8
store i32 0, i32* %9
br label %12
12: ; preds = %37, %3
%13 = load i32, i32* %9
%14 = load i32, i32* %6
%15 = icmp slt i32 %13, %14
br i1 %15, label %16, label %40
16: ; preds = %12
%17 = load i32, i32* %9
%18 = and i32 %17, 1
%19 = icmp ne i32 %18, 0
br i1 %19, label %20, label %28
20: ; preds = %16
%21 = load i32*, i32** %7
%22 = load i32, i32* %21
%23 = ashr i32 %22, 4
%24 = load i32*, i32** %8
%25 = getelementptr inbounds i32, i32* %24, i32 1
store i32* %25, i32** %8
store i32 %23, i32* %24
%26 = load i32*, i32** %7
%27 = getelementptr inbounds i32, i32* %26, i64 2
store i32* %27, i32** %7
br label %36
28: ; preds = %16
%29 = load i32*, i32** %7
%30 = load i32, i32* %29
%31 = and i32 %30, 4095
%32 = load i32*, i32** %8
%33 = getelementptr inbounds i32, i32* %32, i32 1
store i32* %33, i32** %8
store i32 %31, i32* %32
%34 = load i32*, i32** %7
%35 = getelementptr inbounds i32, i32* %34, i32 1
store i32* %35, i32** %7
br label %36
36: ; preds = %28, %20
br label %37
37: ; preds = %36
%38 = load i32, i32* %9
%39 = add nsw i32 %38, 1
store i32 %39, i32* %9
br label %12
40: ; preds = %12
ret i32 0
}

LLVM IR (-O2):
define i32 @ConvertFat12to16(i32* nocapture writeonly %0, i32* nocapture %1, i32 %2) {
%4 = icmp sgt i32 %2, 0
br i1 %4, label %5, label %31
5: ; preds = %3
%6 = and i32 %2, 1
%7 = icmp eq i32 %2, 1
br i1 %7, label %24, label %8
8: ; preds = %5
%9 = and i32 %2, -2
br label %10
10: ; preds = %10, %8
%11 = phi i32* [ %0, %8 ], [ %21, %10 ]
%12 = phi i32* [ %1, %8 ], [ %20, %10 ]
%13 = phi i32 [ 0, %8 ], [ %22, %10 ]
%14 = load i32, i32* %12
%15 = and i32 %14, 4095
store i32 %15, i32* %11
%16 = getelementptr inbounds i32, i32* %12, i64 1
%17 = getelementptr inbounds i32, i32* %11, i64 1
%18 = load i32, i32* %16
%19 = ashr i32 %18, 4
store i32 %19, i32* %17
%20 = getelementptr inbounds i32, i32* %12, i64 3
%21 = getelementptr inbounds i32, i32* %11, i64 2
%22 = add i32 %13, 2
%23 = icmp eq i32 %22, %9
br i1 %23, label %24, label %10
24: ; preds = %10, %5
%25 = phi i32* [ %0, %5 ], [ %21, %10 ]
%26 = phi i32* [ %1, %5 ], [ %20, %10 ]
%27 = icmp eq i32 %6, 0
br i1 %27, label %31, label %28
28: ; preds = %24
%29 = load i32, i32* %26
%30 = and i32 %29, 4095
store i32 %30, i32* %25
br label %31
31: ; preds = %28, %24, %3
ret i32 0
}