#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 uint32_t;
typedef scalar_t__ uint16_t;

/* Variables and functions */
const uint16_t bcm2835_aux_spi_CalcClockDivider(uint32_t speed_hz) {
  uint16_t divider;
  if (speed_hz < (uint32_t)30500) {
    speed_hz = (uint32_t)30500;
  } else if (speed_hz > (uint32_t)125000000) {
    speed_hz = (uint32_t)125000000;
  }
  divider = (uint16_t)(((250000000) + (2 * speed_hz) - 1) / (2 * speed_hz)) - 1;
  if (divider > (uint16_t)0xFFF) {
    return (uint16_t)0xFFF;
  }
  return divider;
}


x86 assembly (clang, -O0):
<bcm2835_aux_spi_CalcClockDivider>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
cmpl   $0x7724,-0xc(%rbp)
jge    1120 <bcm2835_aux_spi_CalcClockDivider+0x20>
movl   $0x7724,-0xc(%rbp)
jmp    1139 <bcm2835_aux_spi_CalcClockDivider+0x39>
cmpl   $0x7735940,-0xc(%rbp)
jle    1134 <bcm2835_aux_spi_CalcClockDivider+0x34>
movl   $0x7735940,-0xc(%rbp)
jmp    1139 <bcm2835_aux_spi_CalcClockDivider+0x39>
mov    -0xc(%rbp),%eax
shl    $0x1,%eax
add    $0xee6b280,%eax
sub    $0x1,%eax
mov    -0xc(%rbp),%ecx
shl    $0x1,%ecx
cltd
idiv   %ecx
cltq
sub    $0x1,%rax
mov    %rax,-0x18(%rbp)
cmpq   $0xfff,-0x18(%rbp)
jle    1175 <bcm2835_aux_spi_CalcClockDivider+0x75>
movq   $0xfff,-0x8(%rbp)
jmp    117d <bcm2835_aux_spi_CalcClockDivider+0x7d>
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<bcm2835_aux_spi_CalcClockDivider>:
cmp    $0x7735940,%edi
mov    $0x7735940,%eax
cmovl  %edi,%eax
add    %eax,%eax
cmp    $0x7724,%edi
mov    $0xee48,%ecx
cmovge %eax,%ecx
lea    0xee6b27f(%rcx),%eax
cltd
idiv   %ecx
cltq
lea    -0x1(%rax),%rcx
cmp    $0x1001,%eax
mov    $0xfff,%eax
cmovl  %rcx,%rax
ret

LLVM IR (-O0):
define i64 @bcm2835_aux_spi_CalcClockDivider(i32 %0) {
%2 = alloca i64
%3 = alloca i32
%4 = alloca i64
store i32 %0, i32* %3
%5 = load i32, i32* %3
%6 = icmp slt i32 %5, 30500
br i1 %6, label %7, label %8
7: ; preds = %1
store i32 30500, i32* %3
br label %13
8: ; preds = %1
%9 = load i32, i32* %3
%10 = icmp sgt i32 %9, 125000000
br i1 %10, label %11, label %12
11: ; preds = %8
store i32 125000000, i32* %3
br label %12
12: ; preds = %11, %8
br label %13
13: ; preds = %12, %7
%14 = load i32, i32* %3
%15 = mul nsw i32 2, %14
%16 = add nsw i32 250000000, %15
%17 = sub nsw i32 %16, 1
%18 = load i32, i32* %3
%19 = mul nsw i32 2, %18
%20 = sdiv i32 %17, %19
%21 = sext i32 %20 to i64
%22 = sub nsw i64 %21, 1
store i64 %22, i64* %4
%23 = load i64, i64* %4
%24 = icmp sgt i64 %23, 4095
br i1 %24, label %25, label %26
25: ; preds = %13
store i64 4095, i64* %2
br label %28
26: ; preds = %13
%27 = load i64, i64* %4
store i64 %27, i64* %2
br label %28
28: ; preds = %26, %25
%29 = load i64, i64* %2
ret i64 %29
}

LLVM IR (-O2):
define i64 @bcm2835_aux_spi_CalcClockDivider(i32 %0) {
%2 = icmp slt i32 %0, 30500
%3 = icmp slt i32 %0, 125000000
%4 = select i1 %3, i32 %0, i32 125000000
%5 = shl i32 %4, 1
%6 = select i1 %2, i32 61000, i32 %5
%7 = add nsw i32 %6, 249999999
%8 = sdiv i32 %7, %6
%9 = icmp sgt i32 %8, 4096
%10 = sext i32 %8 to i64
%11 = add nsw i64 %10, -1
%12 = select i1 %9, i64 4095, i64 %11
ret i64 %12
}