#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 /*<<< orphan*/ printf(char *, long);
int base(long n) {
  long c, r, b = 2;
  if (n == 0)
    return 0;
  c = n / b;
  r = n - b * c;
  if (r < 0) {
    n = c + 1;
    r = r + (-1) * b;
  } else
    n = c;
  base(n);
  printf("%ld", r);
  return 0;
}


x86 assembly (clang, -O0):
<base>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
movq   $0x2,-0x28(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    114b <base+0x2b>
movl   $0x0,-0x4(%rbp)
jmp    11c1 <base+0xa1>
mov    -0x10(%rbp),%rax
cqto
idivq  -0x28(%rbp)
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
imul   -0x18(%rbp),%rcx
sub    %rcx,%rax
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
jge    1199 <base+0x79>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x20(%rbp),%rax
imul   $0xffffffffffffffff,-0x28(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
jmp    11a1 <base+0x81>
mov    -0x18(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <base@plt>
mov    -0x20(%rbp),%rsi
lea    0xe4b(%rip),%rdi
call   1040 <printf@plt>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<base>:
test   %rdi,%rdi
je     1171 <base+0x51>
push   %rbx
mov    %rdi,%rcx
shr    $0x3f,%rcx
add    %rdi,%rcx
mov    %rcx,%rdx
sar    %rdx
and    $0xfffffffffffffffe,%rcx
mov    %rdi,%rsi
sub    %rcx,%rsi
neg    %rcx
mov    %rsi,%rax
shr    $0x3f,%rax
add    %rdx,%rax
test   %rsi,%rsi
lea    -0x2(%rdi,%rcx,1),%rbx
cmovns %rsi,%rbx
mov    %rax,%rdi
call   1030 <base@plt>
lea    0xe98(%rip),%rdi
mov    %rbx,%rsi
call   1040 <printf@plt>
pop    %rbx
xor    %eax,%eax
ret

LLVM IR (-O0):
@.str = [4 x i8] c"%ld\00"
define i32 @base(i64 %0) {
%2 = alloca i32
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
store i64 %0, i64* %3
store i64 2, i64* %6
%7 = load i64, i64* %3
%8 = icmp eq i64 %7, 0
br i1 %8, label %9, label %10
9: ; preds = %1
store i32 0, i32* %2
br label %35
10: ; preds = %1
%11 = load i64, i64* %3
%12 = load i64, i64* %6
%13 = sdiv i64 %11, %12
store i64 %13, i64* %4
%14 = load i64, i64* %3
%15 = load i64, i64* %6
%16 = load i64, i64* %4
%17 = mul nsw i64 %15, %16
%18 = sub nsw i64 %14, %17
store i64 %18, i64* %5
%19 = load i64, i64* %5
%20 = icmp slt i64 %19, 0
br i1 %20, label %21, label %28
21: ; preds = %10
%22 = load i64, i64* %4
%23 = add nsw i64 %22, 1
store i64 %23, i64* %3
%24 = load i64, i64* %5
%25 = load i64, i64* %6
%26 = mul nsw i64 -1, %25
%27 = add nsw i64 %24, %26
store i64 %27, i64* %5
br label %30
28: ; preds = %10
%29 = load i64, i64* %4
store i64 %29, i64* %3
br label %30
30: ; preds = %28, %21
%31 = load i64, i64* %3
%32 = call i32 @base(i64 %31)
%33 = load i64, i64* %5
%34 = call i32 @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i64 %33)
store i32 0, i32* %2
br label %35
35: ; preds = %30, %9
%36 = load i32, i32* %2
ret i32 %36
}

LLVM IR (-O2):
@.str = [4 x i8] c"%ld\00"
define i32 @base(i64 %0) {
%2 = icmp eq i64 %0, 0
br i1 %2, label %3, label %4
3: ; preds = %1, %4
ret i32 0
4: ; preds = %1
%5 = sdiv i64 %0, 2
%6 = mul i64 %5, -2
%7 = add i64 %6, %0
%8 = icmp slt i64 %7, 0
%9 = add nsw i64 %7, -2
%10 = lshr i64 %7, 63
%11 = add nsw i64 %10, %5
%12 = select i1 %8, i64 %9, i64 %7
%13 = tail call i32 @base(i64 %11)
%14 = tail call i32 @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i64 %12)
br label %3
}