#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 last_bit(unsigned long long);
unsigned long long flip_C2(const unsigned long long discs_player,
                           const unsigned long long discs_opponent) {
  unsigned long long my_discs, opp_discs, r;
  unsigned long long flipped =
      (discs_opponent & 0X0000400000000000ULL) & (discs_player << 7);
  my_discs = discs_player & 0X0000002020202020ULL;
  opp_discs = (discs_opponent & 0X0000202020202000ULL) | 0X001FDFDFDFDFC000ULL;
  r = ((my_discs << 8) + opp_discs) & 0X0020000000000000ULL;
  if (r != 0) {
    flipped |= (0X0020000000000000ULL - (0X2ULL << last_bit(my_discs))) &
               0X0000202020202000ULL;
  }
  my_discs = discs_player & 0X0000000804020100ULL;
  opp_discs = (discs_opponent & 0X0000100804020000ULL) | 0X001FEFF7FBFC0000ULL;
  r = ((my_discs << 9) + opp_discs) & 0X0020000000000000ULL;
  if (r != 0) {
    flipped |= (0X0020000000000000ULL - (0X2ULL << last_bit(my_discs))) &
               0X0000100804020000ULL;
  }
  my_discs = discs_player & 0X000F000000000000ULL;
  r = ((my_discs << 1) + discs_opponent) & 0X0020000000000000ULL;
  if (r != 0) {
    flipped |= 0X0020000000000000ULL - (0X2ULL << last_bit(my_discs));
  }
  flipped |= (discs_opponent & 0X0040000000000000ULL) & (discs_player >> 1);
  return flipped;
}


x86 assembly (clang, -O0):
<flip_C2>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movabs $0x400000000000,%rax
and    -0x10(%rbp),%rax
mov    -0x8(%rbp),%rcx
shl    $0x7,%rcx
and    %rcx,%rax
mov    %rax,-0x30(%rbp)
movabs $0x2020202020,%rax
and    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
movabs $0x202020202000,%rax
and    -0x10(%rbp),%rax
movabs $0x1fdfdfdfdfc000,%rcx
or     %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
shl    $0x8,%rax
add    -0x20(%rbp),%rax
movabs $0x20000000000000,%rcx
and    %rcx,%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     11d0 <flip_C2+0xc0>
mov    -0x18(%rbp),%rdi
call   1030 <last_bit@plt>
mov    %eax,%eax
mov    %eax,%ecx
mov    $0x2,%eax
shl    %cl,%rax
mov    %rax,%rcx
movabs $0x20000000000000,%rax
sub    %rcx,%rax
movabs $0x202020202000,%rcx
and    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
movabs $0x804020100,%rax
and    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
movabs $0x100804020000,%rax
and    -0x10(%rbp),%rax
movabs $0x1feff7fbfc0000,%rcx
or     %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
shl    $0x9,%rax
add    -0x20(%rbp),%rax
movabs $0x20000000000000,%rcx
and    %rcx,%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     1263 <flip_C2+0x153>
mov    -0x18(%rbp),%rdi
call   1030 <last_bit@plt>
mov    %eax,%eax
mov    %eax,%ecx
mov    $0x2,%eax
shl    %cl,%rax
mov    %rax,%rcx
movabs $0x20000000000000,%rax
sub    %rcx,%rax
movabs $0x100804020000,%rcx
and    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
movabs $0xf000000000000,%rax
and    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
shl    $0x1,%rax
add    -0x10(%rbp),%rax
movabs $0x20000000000000,%rcx
and    %rcx,%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     12ca <flip_C2+0x1ba>
mov    -0x18(%rbp),%rdi
call   1030 <last_bit@plt>
mov    %eax,%eax
mov    %eax,%ecx
mov    $0x2,%eax
shl    %cl,%rax
mov    %rax,%rcx
movabs $0x20000000000000,%rax
sub    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
movabs $0x40000000000000,%rax
and    -0x10(%rbp),%rax
mov    -0x8(%rbp),%rcx
shr    $0x1,%rcx
and    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<flip_C2>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rsi,%r14
mov    %rdi,%rbx
movabs $0x20000000000000,%r12
movabs $0x202020202000,%r13
mov    %rdi,%rax
shl    $0x7,%rax
and    %rsi,%rax
movabs $0x400000000000,%r15
and    %rax,%r15
movabs $0x2020202020,%rdi
and    %rbx,%rdi
mov    %rsi,%rax
and    %r13,%rax
mov    %rdi,%rcx
shl    $0x8,%rcx
add    %rax,%rcx
movabs $0x1fdfdfdfdfc000,%rax
add    %rcx,%rax
bt     $0x35,%rax
jae    1192 <flip_C2+0x82>
call   1030 <last_bit@plt>
mov    $0xfffffffffffffffe,%rdx
mov    %eax,%ecx
shl    %cl,%rdx
and    %r13,%rdx
or     %rdx,%r15
movabs $0x100804020000,%r13
movabs $0x804020100,%rdi
and    %rbx,%rdi
mov    %r14,%rax
and    %r13,%rax
mov    %rdi,%rcx
shl    $0x9,%rcx
add    %rax,%rcx
movabs $0x1feff7fbfc0000,%rax
add    %rcx,%rax
test   %r12,%rax
je     11e2 <flip_C2+0xd2>
call   1030 <last_bit@plt>
mov    $0xfffffffffffffffe,%rdx
mov    %eax,%ecx
shl    %cl,%rdx
and    %r13,%rdx
or     %rdx,%r15
movabs $0xf000000000000,%rdi
and    %rbx,%rdi
lea    (%r14,%rdi,2),%rax
test   %r12,%rax
je     120f <flip_C2+0xff>
call   1030 <last_bit@plt>
mov    $0xfffffffffffffffe,%rdx
mov    %eax,%ecx
shl    %cl,%rdx
add    %r12,%rdx
or     %rdx,%r15
shr    %rbx
and    %rbx,%r14
movabs $0x40000000000000,%rax
and    %r14,%rax
or     %r15,%rax
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define i64 @flip_C2(i64 %0, i64 %1) {
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64
store i64 %0, i64* %3
store i64 %1, i64* %4
%9 = load i64, i64* %4
%10 = and i64 %9, 70368744177664
%11 = load i64, i64* %3
%12 = shl i64 %11, 7
%13 = and i64 %10, %12
store i64 %13, i64* %8
%14 = load i64, i64* %3
%15 = and i64 %14, 137977929760
store i64 %15, i64* %5
%16 = load i64, i64* %4
%17 = and i64 %16, 35322350018560
%18 = or i64 %17, 8971876904714240
store i64 %18, i64* %6
%19 = load i64, i64* %5
%20 = shl i64 %19, 8
%21 = load i64, i64* %6
%22 = add i64 %20, %21
%23 = and i64 %22, 9007199254740992
store i64 %23, i64* %7
%24 = load i64, i64* %7
%25 = icmp ne i64 %24, 0
br i1 %25, label %26, label %35
26: ; preds = %2
%27 = load i64, i64* %5
%28 = call i32 @last_bit(i64 %27)
%29 = zext i32 %28 to i64
%30 = shl i64 2, %29
%31 = sub i64 9007199254740992, %30
%32 = and i64 %31, 35322350018560
%33 = load i64, i64* %8
%34 = or i64 %33, %32
store i64 %34, i64* %8
br label %35
35: ; preds = %26, %2
%36 = load i64, i64* %3
%37 = and i64 %36, 34426978560
store i64 %37, i64* %5
%38 = load i64, i64* %4
%39 = and i64 %38, 17626613022720
%40 = or i64 %39, 8989572641587200
store i64 %40, i64* %6
%41 = load i64, i64* %5
%42 = shl i64 %41, 9
%43 = load i64, i64* %6
%44 = add i64 %42, %43
%45 = and i64 %44, 9007199254740992
store i64 %45, i64* %7
%46 = load i64, i64* %7
%47 = icmp ne i64 %46, 0
br i1 %47, label %48, label %57
48: ; preds = %35
%49 = load i64, i64* %5
%50 = call i32 @last_bit(i64 %49)
%51 = zext i32 %50 to i64
%52 = shl i64 2, %51
%53 = sub i64 9007199254740992, %52
%54 = and i64 %53, 17626613022720
%55 = load i64, i64* %8
%56 = or i64 %55, %54
store i64 %56, i64* %8
br label %57
57: ; preds = %48, %35
%58 = load i64, i64* %3
%59 = and i64 %58, 4222124650659840
store i64 %59, i64* %5
%60 = load i64, i64* %5
%61 = shl i64 %60, 1
%62 = load i64, i64* %4
%63 = add i64 %61, %62
%64 = and i64 %63, 9007199254740992
store i64 %64, i64* %7
%65 = load i64, i64* %7
%66 = icmp ne i64 %65, 0
br i1 %66, label %67, label %75
67: ; preds = %57
%68 = load i64, i64* %5
%69 = call i32 @last_bit(i64 %68)
%70 = zext i32 %69 to i64
%71 = shl i64 2, %70
%72 = sub i64 9007199254740992, %71
%73 = load i64, i64* %8
%74 = or i64 %73, %72
store i64 %74, i64* %8
br label %75
75: ; preds = %67, %57
%76 = load i64, i64* %4
%77 = and i64 %76, 18014398509481984
%78 = load i64, i64* %3
%79 = lshr i64 %78, 1
%80 = and i64 %77, %79
%81 = load i64, i64* %8
%82 = or i64 %81, %80
store i64 %82, i64* %8
%83 = load i64, i64* %8
ret i64 %83
}

LLVM IR (-O2):
define i64 @flip_C2(i64 %0, i64 %1) {
%3 = and i64 %1, 70368744177664
%4 = shl i64 %0, 7
%5 = and i64 %3, %4
%6 = and i64 %0, 137977929760
%7 = and i64 %1, 35322350018560
%8 = or i64 %7, 8971876904714240
%9 = shl nuw nsw i64 %6, 8
%10 = add nuw nsw i64 %8, %9
%11 = and i64 %10, 9007199254740992
%12 = icmp eq i64 %11, 0
br i1 %12, label %19, label %13
13: ; preds = %2
%14 = tail call i32 @last_bit(i64 %6)
%15 = zext i32 %14 to i64
%16 = shl i64 -2, %15
%17 = and i64 %16, 35322350018560
%18 = or i64 %17, %5
br label %19
19: ; preds = %13, %2
%20 = phi i64 [ %18, %13 ], [ %5, %2 ]
%21 = and i64 %0, 34426978560
%22 = and i64 %1, 17626613022720
%23 = or i64 %22, 8989572641587200
%24 = shl nuw nsw i64 %21, 9
%25 = add nuw nsw i64 %23, %24
%26 = and i64 %25, 9007199254740992
%27 = icmp eq i64 %26, 0
br i1 %27, label %34, label %28
28: ; preds = %19
%29 = tail call i32 @last_bit(i64 %21)
%30 = zext i32 %29 to i64
%31 = shl i64 -2, %30
%32 = and i64 %31, 17626613022720
%33 = or i64 %32, %20
br label %34
34: ; preds = %28, %19
%35 = phi i64 [ %33, %28 ], [ %20, %19 ]
%36 = and i64 %0, 4222124650659840
%37 = shl nuw nsw i64 %36, 1
%38 = add i64 %37, %1
%39 = and i64 %38, 9007199254740992
%40 = icmp eq i64 %39, 0
br i1 %40, label %47, label %41
41: ; preds = %34
%42 = tail call i32 @last_bit(i64 %36)
%43 = zext i32 %42 to i64
%44 = shl i64 -2, %43
%45 = add i64 %44, 9007199254740992
%46 = or i64 %45, %35
br label %47
47: ; preds = %41, %34
%48 = phi i64 [ %46, %41 ], [ %35, %34 ]
%49 = and i64 %1, 18014398509481984
%50 = lshr i64 %0, 1
%51 = and i64 %49, %50
%52 = or i64 %48, %51
ret i64 %52
}