short threegpp_interleaver_parameters(unsigned short bytes_per_codeword) {
  if (bytes_per_codeword <= 64)
    return (bytes_per_codeword - 5);
  else if (bytes_per_codeword <= 128)
    return (59 + ((bytes_per_codeword - 64) >> 1));
  else if (bytes_per_codeword <= 256)
    return (91 + ((bytes_per_codeword - 128) >> 2));
  else if (bytes_per_codeword <= 768)
    return (123 + ((bytes_per_codeword - 256) >> 3));
  else {
    return (-1);
  }
}


x86 assembly (clang, -O0):
<threegpp_interleaver_parameters>:
push   %rbp
mov    %rsp,%rbp
mov    %di,%ax
mov    %ax,-0x4(%rbp)
movzwl -0x4(%rbp),%eax
cmp    $0x40,%eax
jg     1128 <threegpp_interleaver_parameters+0x28>
movzwl -0x4(%rbp),%eax
sub    $0x5,%eax
mov    %ax,-0x2(%rbp)
jmp    11a1 <threegpp_interleaver_parameters+0xa1>
movzwl -0x4(%rbp),%eax
cmp    $0x80,%eax
jg     114d <threegpp_interleaver_parameters+0x4d>
movzwl -0x4(%rbp),%eax
sub    $0x40,%eax
sar    $0x1,%eax
add    $0x3b,%eax
mov    %ax,-0x2(%rbp)
jmp    11a1 <threegpp_interleaver_parameters+0xa1>
movzwl -0x4(%rbp),%eax
cmp    $0x100,%eax
jg     1174 <threegpp_interleaver_parameters+0x74>
movzwl -0x4(%rbp),%eax
sub    $0x80,%eax
sar    $0x2,%eax
add    $0x5b,%eax
mov    %ax,-0x2(%rbp)
jmp    11a1 <threegpp_interleaver_parameters+0xa1>
movzwl -0x4(%rbp),%eax
cmp    $0x300,%eax
jg     119b <threegpp_interleaver_parameters+0x9b>
movzwl -0x4(%rbp),%eax
sub    $0x100,%eax
sar    $0x3,%eax
add    $0x7b,%eax
mov    %ax,-0x2(%rbp)
jmp    11a1 <threegpp_interleaver_parameters+0xa1>
movw   $0xffff,-0x2(%rbp)
movswl -0x2(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<threegpp_interleaver_parameters>:
cmp    $0x40,%di
ja     110a <threegpp_interleaver_parameters+0xa>
lea    -0x5(%rdi),%eax
ret
movzwl %di,%ecx
cmp    $0x80,%ecx
ja     1122 <threegpp_interleaver_parameters+0x22>
add    $0x1ffc0,%edi
shr    %edi
add    $0x3b,%edi
jmp    1150 <threegpp_interleaver_parameters+0x50>
cmp    $0x100,%ecx
ja     1138 <threegpp_interleaver_parameters+0x38>
add    $0x3ff80,%edi
shr    $0x2,%edi
add    $0x5b,%edi
jmp    1150 <threegpp_interleaver_parameters+0x50>
mov    $0xffff,%ax
cmp    $0x300,%ecx
ja     1152 <threegpp_interleaver_parameters+0x52>
add    $0x7ff00,%edi
shr    $0x3,%edi
add    $0x7b,%edi
mov    %edi,%eax
ret

LLVM IR (-O0):
define signext i16 @threegpp_interleaver_parameters(i16 zeroext %0) {
%2 = alloca i16
%3 = alloca i16
store i16 %0, i16* %3
%4 = load i16, i16* %3
%5 = zext i16 %4 to i32
%6 = icmp sle i32 %5, 64
br i1 %6, label %7, label %12
7: ; preds = %1
%8 = load i16, i16* %3
%9 = zext i16 %8 to i32
%10 = sub nsw i32 %9, 5
%11 = trunc i32 %10 to i16
store i16 %11, i16* %2
br label %46
12: ; preds = %1
%13 = load i16, i16* %3
%14 = zext i16 %13 to i32
%15 = icmp sle i32 %14, 128
br i1 %15, label %16, label %23
16: ; preds = %12
%17 = load i16, i16* %3
%18 = zext i16 %17 to i32
%19 = sub nsw i32 %18, 64
%20 = ashr i32 %19, 1
%21 = add nsw i32 59, %20
%22 = trunc i32 %21 to i16
store i16 %22, i16* %2
br label %46
23: ; preds = %12
%24 = load i16, i16* %3
%25 = zext i16 %24 to i32
%26 = icmp sle i32 %25, 256
br i1 %26, label %27, label %34
27: ; preds = %23
%28 = load i16, i16* %3
%29 = zext i16 %28 to i32
%30 = sub nsw i32 %29, 128
%31 = ashr i32 %30, 2
%32 = add nsw i32 91, %31
%33 = trunc i32 %32 to i16
store i16 %33, i16* %2
br label %46
34: ; preds = %23
%35 = load i16, i16* %3
%36 = zext i16 %35 to i32
%37 = icmp sle i32 %36, 768
br i1 %37, label %38, label %45
38: ; preds = %34
%39 = load i16, i16* %3
%40 = zext i16 %39 to i32
%41 = sub nsw i32 %40, 256
%42 = ashr i32 %41, 3
%43 = add nsw i32 123, %42
%44 = trunc i32 %43 to i16
store i16 %44, i16* %2
br label %46
45: ; preds = %34
store i16 -1, i16* %2
br label %46
46: ; preds = %45, %38, %27, %16, %7
%47 = load i16, i16* %2
ret i16 %47
}

LLVM IR (-O2):
define signext i16 @threegpp_interleaver_parameters(i16 zeroext %0) {
%2 = zext i16 %0 to i32
%3 = icmp ult i16 %0, 65
br i1 %3, label %4, label %6
4: ; preds = %1
%5 = add nsw i16 %0, -5
br label %27
6: ; preds = %1
%7 = icmp ult i16 %0, 129
br i1 %7, label %8, label %13
8: ; preds = %6
%9 = add nuw nsw i32 %2, 131008
%10 = lshr i32 %9, 1
%11 = trunc i32 %10 to i16
%12 = add i16 %11, 59
br label %27
13: ; preds = %6
%14 = icmp ult i16 %0, 257
br i1 %14, label %15, label %20
15: ; preds = %13
%16 = add nuw nsw i32 %2, 262016
%17 = lshr i32 %16, 2
%18 = trunc i32 %17 to i16
%19 = add nsw i16 %18, 91
br label %27
20: ; preds = %13
%21 = icmp ult i16 %0, 769
br i1 %21, label %22, label %27
22: ; preds = %20
%23 = add nuw nsw i32 %2, 524032
%24 = lshr i32 %23, 3
%25 = trunc i32 %24 to i16
%26 = add nsw i16 %25, 123
br label %27
27: ; preds = %20, %22, %15, %8, %4
%28 = phi i16 [ %5, %4 ], [ %12, %8 ], [ %19, %15 ], [ %26, %22 ], [ -1, %20 ]
ret i16 %28
}