#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 uint8_t;
typedef int uint16_t;

/* Variables and functions */
void convertpalette(char *in, char *out) {
  uint16_t tgtcol;
  int pc;
  uint8_t r, g, b;
  for (pc = 0; pc < 256; pc++) {
    b = in[pc * 3 + 0];
    g = in[pc * 3 + 1];
    r = in[pc * 3 + 2];
    tgtcol = ((b & 0xf8) << 7) | ((g & 0xf8) << 2) | ((r & 0xf8) >> 3);
    out[pc * 2 + 0] = tgtcol & 0xff;
    out[pc * 2 + 1] = tgtcol >> 8;
  }
}


x86 assembly (clang, -O0):
<convertpalette>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x18(%rbp)
cmpl   $0x100,-0x18(%rbp)
jge    11cf <convertpalette+0xcf>
mov    -0x8(%rbp),%rax
imul   $0x3,-0x18(%rbp),%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
mov    %eax,-0x24(%rbp)
mov    -0x8(%rbp),%rax
imul   $0x3,-0x18(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
mov    %eax,-0x20(%rbp)
mov    -0x8(%rbp),%rax
imul   $0x3,-0x18(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x24(%rbp),%eax
and    $0xf8,%eax
shl    $0x7,%eax
mov    -0x20(%rbp),%ecx
and    $0xf8,%ecx
shl    $0x2,%ecx
or     %ecx,%eax
mov    -0x1c(%rbp),%ecx
and    $0xf8,%ecx
sar    $0x3,%ecx
or     %ecx,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
and    $0xff,%eax
mov    %al,%dl
mov    -0x10(%rbp),%rax
mov    -0x18(%rbp),%ecx
shl    $0x1,%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
sar    $0x8,%eax
mov    %al,%dl
mov    -0x10(%rbp),%rax
mov    -0x18(%rbp),%ecx
shl    $0x1,%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1113 <convertpalette+0x13>
pop    %rbp
ret

x86 assembly (clang, -O2):
<convertpalette>:
lea    0x300(%rdi),%rax
cmp    %rsi,%rax
jbe    115e <convertpalette+0x5e>
lea    0x200(%rsi),%rax
cmp    %rdi,%rax
jbe    115e <convertpalette+0x5e>
add    $0x2,%rdi
xor    %eax,%eax
xchg   %ax,%ax
movzbl -0x2(%rdi),%ecx
movzbl -0x1(%rdi),%edx
movzbl (%rdi),%r8d
and    $0xfffffff8,%ecx
shl    $0x7,%ecx
and    $0xfffffff8,%edx
lea    (%rcx,%rdx,4),%ecx
shl    $0x2,%edx
shr    $0x3,%r8b
or     %r8b,%dl
mov    %dl,(%rsi,%rax,2)
mov    %ch,0x1(%rsi,%rax,2)
add    $0x1,%rax
add    $0x3,%rdi
cmp    $0x100,%rax
jne    1120 <convertpalette+0x20>
jmp    133b <convertpalette+0x23b>
xor    %eax,%eax
movdqa 0xe97(%rip),%xmm9
pxor   %xmm1,%xmm1
movdqa 0xe9a(%rip),%xmm10
movdqa 0xea1(%rip),%xmm11
movdqa 0xea8(%rip),%xmm12
movdqa 0xeaf(%rip),%xmm13
movdqa 0xeb6(%rip),%xmm15
movdqa 0xebd(%rip),%xmm14
movdqa 0xec4(%rip),%xmm8
movdqa 0xecc(%rip),%xmm0
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movdqu (%rdi),%xmm7
movq   0x10(%rdi),%xmm5
movdqa %xmm9,%xmm2
pandn  %xmm5,%xmm2
movdqa %xmm7,%xmm3
pand   %xmm9,%xmm3
por    %xmm2,%xmm3
punpcklbw %xmm1,%xmm3
pand   %xmm10,%xmm3
movdqa %xmm7,%xmm6
punpckhbw %xmm1,%xmm6
movdqa %xmm10,%xmm2
pandn  %xmm6,%xmm2
por    %xmm3,%xmm2
pshufd $0xd8,%xmm2,%xmm2
pshufhw $0x6c,%xmm2,%xmm2
pshufd $0x6c,%xmm2,%xmm2
pshuflw $0x6c,%xmm2,%xmm2
pshufhw $0xc6,%xmm2,%xmm2
packuswb %xmm2,%xmm2
movdqa %xmm11,%xmm3
pandn  %xmm5,%xmm3
movdqa %xmm7,%xmm4
pand   %xmm11,%xmm4
por    %xmm3,%xmm4
punpcklbw %xmm1,%xmm4
pand   %xmm12,%xmm4
movdqa %xmm12,%xmm3
pandn  %xmm6,%xmm3
por    %xmm4,%xmm3
pshuflw $0xc6,%xmm3,%xmm3
pshufhw $0xc6,%xmm3,%xmm3
pshufd $0x6c,%xmm3,%xmm3
pshuflw $0x39,%xmm3,%xmm3
pshufhw $0x39,%xmm3,%xmm3
packuswb %xmm3,%xmm3
movdqa %xmm13,%xmm4
pandn  %xmm5,%xmm4
pand   %xmm13,%xmm7
por    %xmm4,%xmm7
punpcklbw %xmm1,%xmm7
pand   %xmm15,%xmm7
movdqa %xmm15,%xmm4
pandn  %xmm6,%xmm4
por    %xmm7,%xmm4
pshufd $0x27,%xmm4,%xmm4
pshufhw $0x6c,%xmm4,%xmm4
pshufd $0x27,%xmm4,%xmm4
pshuflw $0xc6,%xmm4,%xmm4
pshufhw $0xc6,%xmm4,%xmm5
packuswb %xmm5,%xmm5
pand   %xmm14,%xmm2
punpcklbw %xmm1,%xmm2
movdqa %xmm2,%xmm4
punpcklwd %xmm1,%xmm4
punpckhwd %xmm1,%xmm2
pslld  $0x7,%xmm2
pslld  $0x7,%xmm4
pand   %xmm14,%xmm3
punpcklbw %xmm1,%xmm3
movdqa %xmm3,%xmm7
punpcklwd %xmm1,%xmm7
punpckhwd %xmm1,%xmm3
pslld  $0x2,%xmm3
pslld  $0x2,%xmm7
por    %xmm7,%xmm4
por    %xmm3,%xmm2
psrlw  $0x3,%xmm5
pand   %xmm8,%xmm5
pand   %xmm0,%xmm3
pand   %xmm0,%xmm7
packuswb %xmm3,%xmm7
packuswb %xmm7,%xmm7
por    %xmm5,%xmm7
psrld  $0x8,%xmm2
psrld  $0x8,%xmm4
packuswb %xmm2,%xmm4
packuswb %xmm4,%xmm4
punpcklbw %xmm4,%xmm7
movdqu %xmm7,(%rsi,%rax,2)
add    $0x8,%rax
add    $0x18,%rdi
cmp    $0x100,%rax
jne    11c0 <convertpalette+0xc0>
ret

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

LLVM IR (-O2):
define void @convertpalette(i8* nocapture %0, i8* nocapture writeonly %1) {
%3 = getelementptr i8, i8* %1, i64 512
%4 = getelementptr i8, i8* %0, i64 768
%5 = icmp ugt i8* %4, %1
%6 = icmp ugt i8* %3, %0
%7 = and i1 %5, %6
br i1 %7, label %38, label %8
8: ; preds = %2
%9 = getelementptr inbounds i8, i8* %1, i64 -1
br label %10
10: ; preds = %8, %10
%11 = phi i64 [ %36, %10 ], [ 0, %8 ]
%12 = mul nuw nsw i64 %11, 3
%13 = getelementptr inbounds i8, i8* %0, i64 %12
%14 = bitcast i8* %13 to <24 x i8>*
%15 = load <24 x i8>, <24 x i8>* %14
%16 = shufflevector <24 x i8> %15, <24 x i8> poison, <8 x i32> <i32 0, i32 3, i32 6, i32 9, i32 12, i32 15, i32 18, i32 21>
%17 = shufflevector <24 x i8> %15, <24 x i8> poison, <8 x i32> <i32 1, i32 4, i32 7, i32 10, i32 13, i32 16, i32 19, i32 22>
%18 = shufflevector <24 x i8> %15, <24 x i8> poison, <8 x i32> <i32 2, i32 5, i32 8, i32 11, i32 14, i32 17, i32 20, i32 23>
%19 = and <8 x i8> %16, <i8 -8, i8 -8, i8 -8, i8 -8, i8 -8, i8 -8, i8 -8, i8 -8>
%20 = zext <8 x i8> %19 to <8 x i32>
%21 = shl nuw nsw <8 x i32> %20, <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7>
%22 = and <8 x i8> %17, <i8 -8, i8 -8, i8 -8, i8 -8, i8 -8, i8 -8, i8 -8, i8 -8>
%23 = zext <8 x i8> %22 to <8 x i32>
%24 = shl nuw nsw <8 x i32> %23, <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
%25 = or <8 x i32> %24, %21
%26 = lshr <8 x i8> %18, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3>
%27 = trunc <8 x i32> %24 to <8 x i8>
%28 = or <8 x i8> %26, %27
%29 = shl nuw nsw i64 %11, 1
%30 = lshr <8 x i32> %25, <i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8>
%31 = trunc <8 x i32> %30 to <8 x i8>
%32 = or i64 %29, 1
%33 = getelementptr inbounds i8, i8* %9, i64 %32
%34 = bitcast i8* %33 to <16 x i8>*
%35 = shufflevector <8 x i8> %28, <8 x i8> %31, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
store <16 x i8> %35, <16 x i8>* %34
%36 = add nuw i64 %11, 8
%37 = icmp eq i64 %36, 256
br i1 %37, label %67, label %10
38: ; preds = %2, %38
%39 = phi i64 [ %65, %38 ], [ 0, %2 ]
%40 = mul nuw nsw i64 %39, 3
%41 = getelementptr inbounds i8, i8* %0, i64 %40
%42 = load i8, i8* %41
%43 = add nuw nsw i64 %40, 1
%44 = getelementptr inbounds i8, i8* %0, i64 %43
%45 = load i8, i8* %44
%46 = add nuw nsw i64 %40, 2
%47 = getelementptr inbounds i8, i8* %0, i64 %46
%48 = load i8, i8* %47
%49 = and i8 %42, -8
%50 = zext i8 %49 to i32
%51 = shl nuw nsw i32 %50, 7
%52 = and i8 %45, -8
%53 = zext i8 %52 to i32
%54 = shl nuw nsw i32 %53, 2
%55 = or i32 %54, %51
%56 = lshr i8 %48, 3
%57 = trunc i32 %54 to i8
%58 = or i8 %56, %57
%59 = shl nuw nsw i64 %39, 1
%60 = getelementptr inbounds i8, i8* %1, i64 %59
store i8 %58, i8* %60
%61 = lshr i32 %55, 8
%62 = trunc i32 %61 to i8
%63 = or i64 %59, 1
%64 = getelementptr inbounds i8, i8* %1, i64 %63
store i8 %62, i8* %64
%65 = add nuw nsw i64 %39, 1
%66 = icmp eq i64 %65, 256
br i1 %66, label %67, label %38
67: ; preds = %10, %38
ret void
}