#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 */

/* Variables and functions */
int putchar(unsigned short);
int putb(unsigned short b) {
  static unsigned short c = 0, count = 0, bits[8];
  bits[count++ % 8] = b;
  if (count % 8 == 0) {
    c = (bits[0] << 7) | (bits[1] << 6) | (bits[2] << 5) | (bits[3] << 4) |
        (bits[4] << 3) | (bits[5] << 2) | (bits[6] << 1) | (bits[7] << 0);
    return putchar(c);
  }
  return 0;
}


x86 assembly (clang, -O0):
<putb>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %di,%ax
mov    %ax,-0x6(%rbp)
mov    -0x6(%rbp),%ax
mov    %ax,-0x8(%rbp)
mov    0x2f14(%rip),%ax
mov    %ax,%cx
add    $0x1,%cx
mov    %cx,0x2f06(%rip)
movzwl %ax,%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    %edx,%eax
mov    -0x8(%rbp),%dx
movslq %eax,%rcx
lea    0x2ef9(%rip),%rax
mov    %dx,(%rax,%rcx,2)
movzwl 0x2ee0(%rip),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jne    11ec <putb+0xdc>
movzwl 0x2ed6(%rip),%eax
shl    $0x7,%eax
movzwl 0x2ece(%rip),%ecx
shl    $0x6,%ecx
or     %ecx,%eax
movzwl 0x2ec4(%rip),%ecx
shl    $0x5,%ecx
or     %ecx,%eax
movzwl 0x2eba(%rip),%ecx
shl    $0x4,%ecx
or     %ecx,%eax
movzwl 0x2eb0(%rip),%ecx
shl    $0x3,%ecx
or     %ecx,%eax
movzwl 0x2ea6(%rip),%ecx
shl    $0x2,%ecx
or     %ecx,%eax
movzwl 0x2e9c(%rip),%ecx
shl    $0x1,%ecx
or     %ecx,%eax
movzwl 0x2e92(%rip),%ecx
shl    $0x0,%ecx
or     %ecx,%eax
mov    %ax,0x2e68(%rip)
movzwl 0x2e61(%rip),%edi
call   1030 <putchar@plt>
mov    %eax,-0x4(%rbp)
jmp    11f3 <putb+0xe3>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<putb>:
movzwl 0x2f29(%rip),%eax
lea    0x1(%rax),%ecx
mov    %cx,0x2f1f(%rip)
and    $0x7,%eax
lea    0x2f25(%rip),%rdx
mov    %di,(%rdx,%rax,2)
test   $0x7,%cl
je     1137 <putb+0x27>
xor    %eax,%eax
ret
movq   0x2f11(%rip),%xmm0
pmullw 0xeb9(%rip),%xmm0
mov    0x2f0b(%rip),%eax
shl    $0x3,%eax
movzwl 0x2f03(%rip),%ecx
shl    $0x2,%ecx
or     %eax,%ecx
mov    0x2efa(%rip),%eax
add    %eax,%eax
or     %ecx,%eax
pshufd $0x55,%xmm0,%xmm1
por    %xmm0,%xmm1
movdqa %xmm1,%xmm0
psrld  $0x10,%xmm0
por    %xmm1,%xmm0
movd   %xmm0,%ecx
or     %eax,%ecx
or     0x2ed5(%rip),%cx
movzwl %cx,%edi
jmp    1030 <putchar@plt>

LLVM IR (-O0):
@putb.c = internal global i16 0
@putb.count = internal global i16 0
@putb.bits = internal global [8 x i16] zeroinitializer
define i32 @putb(i16 zeroext %0) {
%2 = alloca i32
%3 = alloca i16
store i16 %0, i16* %3
%4 = load i16, i16* %3
%5 = load i16, i16* @putb.count
%6 = add i16 %5, 1
store i16 %6, i16* @putb.count
%7 = zext i16 %5 to i32
%8 = srem i32 %7, 8
%9 = sext i32 %8 to i64
%10 = getelementptr inbounds [8 x i16], [8 x i16]* @putb.bits, i64 0, i64 %9
store i16 %4, i16* %10
%11 = load i16, i16* @putb.count
%12 = zext i16 %11 to i32
%13 = srem i32 %12, 8
%14 = icmp eq i32 %13, 0
br i1 %14, label %15, label %50
15: ; preds = %1
%16 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 0)
%17 = zext i16 %16 to i32
%18 = shl i32 %17, 7
%19 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 1)
%20 = zext i16 %19 to i32
%21 = shl i32 %20, 6
%22 = or i32 %18, %21
%23 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 2)
%24 = zext i16 %23 to i32
%25 = shl i32 %24, 5
%26 = or i32 %22, %25
%27 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 3)
%28 = zext i16 %27 to i32
%29 = shl i32 %28, 4
%30 = or i32 %26, %29
%31 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 4)
%32 = zext i16 %31 to i32
%33 = shl i32 %32, 3
%34 = or i32 %30, %33
%35 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 5)
%36 = zext i16 %35 to i32
%37 = shl i32 %36, 2
%38 = or i32 %34, %37
%39 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 6)
%40 = zext i16 %39 to i32
%41 = shl i32 %40, 1
%42 = or i32 %38, %41
%43 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 7)
%44 = zext i16 %43 to i32
%45 = shl i32 %44, 0
%46 = or i32 %42, %45
%47 = trunc i32 %46 to i16
store i16 %47, i16* @putb.c
%48 = load i16, i16* @putb.c
%49 = call i32 @putchar(i16 zeroext %48)
store i32 %49, i32* %2
br label %51
50: ; preds = %1
store i32 0, i32* %2
br label %51
51: ; preds = %50, %15
%52 = load i32, i32* %2
ret i32 %52
}

LLVM IR (-O2):
@putb.count = internal unnamed_addr global i16 0
@putb.bits = internal unnamed_addr global [8 x i16] zeroinitializer
define i32 @putb(i16 zeroext %0) {
%2 = load i16, i16* @putb.count
%3 = add i16 %2, 1
store i16 %3, i16* @putb.count
%4 = and i16 %2, 7
%5 = zext i16 %4 to i64
%6 = getelementptr inbounds [8 x i16], [8 x i16]* @putb.bits, i64 0, i64 %5
store i16 %0, i16* %6
%7 = and i16 %3, 7
%8 = icmp eq i16 %7, 0
br i1 %8, label %9, label %25
9: ; preds = %1
%10 = load <4 x i16>, <4 x i16>* bitcast ([8 x i16]* @putb.bits to <4 x i16>*)
%11 = shl <4 x i16> %10, <i16 7, i16 6, i16 5, i16 4>
%12 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 4)
%13 = shl i16 %12, 3
%14 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 5)
%15 = shl i16 %14, 2
%16 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 6)
%17 = shl i16 %16, 1
%18 = load i16, i16* getelementptr inbounds ([8 x i16], [8 x i16]* @putb.bits, i64 0, i64 7)
%19 = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> %11)
%20 = or i16 %19, %13
%21 = or i16 %20, %15
%22 = or i16 %21, %17
%23 = or i16 %22, %18
%24 = tail call i32 @putchar(i16 zeroext %23)
br label %25
25: ; preds = %1, %9
%26 = phi i32 [ %24, %9 ], [ 0, %1 ]
ret i32 %26
}