#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 uint32_t;

/* Variables and functions */
void right_shift_key_segment(uint32_t *key_seg, uint8_t round) {
  static const uint8_t shift_table[16] = {1, 2, 2, 2, 2, 2, 2, 1,
                                          2, 2, 2, 2, 2, 2, 1, 1};
  uint32_t mask = 1;
  uint32_t CF = 0;
  uint8_t i;
  for (i = 0; i < shift_table[round]; i++) {
    *key_seg &mask ? CF = 0x8000000 : (CF = 0);
    *key_seg = ((*key_seg >> 1) & 0x07FFFFFF) | CF;
  }
}


x86 assembly (clang, -O0):
<right_shift_key_segment>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movl   $0x1,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
movslq -0xc(%rbp),%rdx
lea    0xed2(%rip),%rcx
cmp    (%rcx,%rdx,4),%eax
jge    1182 <right_shift_key_segment+0x82>
mov    -0x8(%rbp),%rax
mov    (%rax),%eax
and    -0x10(%rbp),%eax
cmp    $0x0,%eax
je     1155 <right_shift_key_segment+0x55>
movl   $0x8000000,-0x14(%rbp)
jmp    115c <right_shift_key_segment+0x5c>
movl   $0x0,-0x14(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%ecx
sar    $0x1,%ecx
and    $0x7ffffff,%ecx
or     -0x14(%rbp),%ecx
mov    -0x8(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1120 <right_shift_key_segment+0x20>
pop    %rbp
ret

x86 assembly (clang, -O2):
<right_shift_key_segment>:
movslq %esi,%rax
lea    0xef6(%rip),%rcx
mov    (%rcx,%rax,4),%eax
cmp    $0x2,%eax
mov    $0x1,%r9d
cmovge %eax,%r9d
mov    (%rdi),%eax
lea    -0x1(%r9),%esi
mov    %r9d,%r8d
and    $0x3,%r8d
cmp    $0x3,%esi
jb     1182 <right_shift_key_segment+0x82>
and    $0x7ffffffc,%r9d
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %eax,%esi
shl    $0x1b,%esi
mov    %eax,%edx
shr    %edx
mov    %edx,%ecx
and    $0x7fffff8,%ecx
or     %esi,%ecx
shl    $0x1b,%edx
shr    %ecx
and    $0x7fffffc,%ecx
or     %edx,%ecx
mov    %eax,%edx
and    $0x4,%edx
shl    $0x19,%edx
shr    %ecx
and    $0x7fffffe,%ecx
or     %edx,%ecx
and    $0x8,%eax
shl    $0x18,%eax
shr    %ecx
or     %ecx,%eax
add    $0xfffffffc,%r9d
jne    1140 <right_shift_key_segment+0x40>
test   %r8d,%r8d
je     11a7 <right_shift_key_segment+0xa7>
nopw   0x0(%rax,%rax,1)
mov    %eax,%ecx
and    $0x1,%ecx
shl    $0x1b,%ecx
shr    %eax
and    $0x7ffffff,%eax
or     %ecx,%eax
add    $0xffffffff,%r8d
jne    1190 <right_shift_key_segment+0x90>
mov    %eax,(%rdi)
ret

LLVM IR (-O0):
@right_shift_key_segment.shift_table = internal constant [16 x i32] [i32 1, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 1, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 1, i32 1]
define void @right_shift_key_segment(i32* %0, i32 %1) {
%3 = alloca i32*
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
store i32* %0, i32** %3
store i32 %1, i32* %4
store i32 1, i32* %5
store i32 0, i32* %6
store i32 0, i32* %7
br label %8
8: ; preds = %32, %2
%9 = load i32, i32* %7
%10 = load i32, i32* %4
%11 = sext i32 %10 to i64
%12 = getelementptr inbounds [16 x i32], [16 x i32]* @right_shift_key_segment.shift_table, i64 0, i64 %11
%13 = load i32, i32* %12
%14 = icmp slt i32 %9, %13
br i1 %14, label %15, label %35
15: ; preds = %8
%16 = load i32*, i32** %3
%17 = load i32, i32* %16
%18 = load i32, i32* %5
%19 = and i32 %17, %18
%20 = icmp ne i32 %19, 0
br i1 %20, label %21, label %22
21: ; preds = %15
store i32 134217728, i32* %6
br label %23
22: ; preds = %15
store i32 0, i32* %6
br label %23
23: ; preds = %22, %21
%24 = phi i32 [ 134217728, %21 ], [ 0, %22 ]
%25 = load i32*, i32** %3
%26 = load i32, i32* %25
%27 = ashr i32 %26, 1
%28 = and i32 %27, 134217727
%29 = load i32, i32* %6
%30 = or i32 %28, %29
%31 = load i32*, i32** %3
store i32 %30, i32* %31
br label %32
32: ; preds = %23
%33 = load i32, i32* %7
%34 = add nsw i32 %33, 1
store i32 %34, i32* %7
br label %8
35: ; preds = %8
ret void
}

LLVM IR (-O2):
@right_shift_key_segment.shift_table = internal unnamed_addr constant [16 x i32] [i32 1, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 1, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 1, i32 1]
define void @right_shift_key_segment(i32* nocapture %0, i32 %1) {
%3 = sext i32 %1 to i64
%4 = getelementptr inbounds [16 x i32], [16 x i32]* @right_shift_key_segment.shift_table, i64 0, i64 %3
%5 = load i32, i32* %4
%6 = load i32, i32* %0
%7 = call i32 @llvm.smax.i32(i32 %5, i32 1)
%8 = add nsw i32 %7, -1
%9 = and i32 %7, 3
%10 = icmp ult i32 %8, 3
br i1 %10, label %35, label %11
11: ; preds = %2
%12 = and i32 %7, 2147483644
br label %13
13: ; preds = %13, %11
%14 = phi i32 [ %6, %11 ], [ %32, %13 ]
%15 = phi i32 [ 0, %11 ], [ %33, %13 ]
%16 = shl i32 %14, 27
%17 = lshr i32 %14, 1
%18 = and i32 %17, 134217720
%19 = or i32 %18, %16
%20 = shl i32 %17, 27
%21 = lshr exact i32 %19, 1
%22 = and i32 %21, 134217724
%23 = or i32 %22, %20
%24 = shl i32 %17, 26
%25 = and i32 %24, 134217728
%26 = lshr exact i32 %23, 1
%27 = and i32 %26, 134217726
%28 = or i32 %27, %25
%29 = shl i32 %17, 25
%30 = and i32 %29, 134217728
%31 = lshr exact i32 %28, 1
%32 = or i32 %31, %30
%33 = add i32 %15, 4
%34 = icmp eq i32 %33, %12
br i1 %34, label %35, label %13
35: ; preds = %13, %2
%36 = phi i32 [ undef, %2 ], [ %32, %13 ]
%37 = phi i32 [ %6, %2 ], [ %32, %13 ]
%38 = icmp eq i32 %9, 0
br i1 %38, label %49, label %39
39: ; preds = %35, %39
%40 = phi i32 [ %46, %39 ], [ %37, %35 ]
%41 = phi i32 [ %47, %39 ], [ 0, %35 ]
%42 = shl i32 %40, 27
%43 = and i32 %42, 134217728
%44 = lshr i32 %40, 1
%45 = and i32 %44, 134217727
%46 = or i32 %45, %43
%47 = add i32 %41, 1
%48 = icmp eq i32 %47, %9
br i1 %48, label %49, label %39
49: ; preds = %39, %35
%50 = phi i32 [ %36, %35 ], [ %46, %39 ]
store i32 %50, i32* %0
ret void
}