#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*/ DEBUG_ASSERT(int);
int SSIBaseValid(unsigned long);
void SSIConfigSetExpClk(unsigned long ulBase, unsigned long ulSSIClk,
                        unsigned long ulProtocol, unsigned long ulMode,
                        unsigned long ulBitRate, unsigned long ulDataWidth) {
  unsigned long ulMaxBitRate;
  unsigned long ulRegVal;
  unsigned long ulPreDiv;
  unsigned long ulSCR;
  unsigned long ulSPH_SPO;
  DEBUG_ASSERT(SSIBaseValid(ulBase));
  DEBUG_ASSERT((ulProtocol == 0x00000000) || (ulProtocol == 0x00000002) ||
               (ulProtocol == 0x00000001) || (ulProtocol == 0x00000003) ||
               (ulProtocol == 0x00000010) || (ulProtocol == 0x00000020));
  DEBUG_ASSERT((ulMode == 0x00000000) || (ulMode == 0x00000001) ||
               (ulMode == 0x00000002));
  DEBUG_ASSERT(((ulMode == 0x00000000) && (ulBitRate <= (ulSSIClk / 2))) ||
               ((ulMode != 0x00000000) && (ulBitRate <= (ulSSIClk / 12))));
  DEBUG_ASSERT((ulSSIClk / ulBitRate) <= (254 * 256));
  DEBUG_ASSERT((ulDataWidth >= 4) && (ulDataWidth <= 16));
  ulRegVal = (ulMode == 0x00000002) ? 0x00000008 : 0;
  ulRegVal |= (ulMode == 0x00000000) ? 0 : 0x00000004;
  (*((volatile unsigned long *)(ulBase + 0x00000004))) = ulRegVal;
  ulMaxBitRate = ulSSIClk / ulBitRate;
  ulPreDiv = 0;
  do {
    ulPreDiv += 2;
    ulSCR = (ulMaxBitRate / ulPreDiv) - 1;
  } while (ulSCR > 255);
  (*((volatile unsigned long *)(ulBase + 0x00000010))) = ulPreDiv;
  ulSPH_SPO = (ulProtocol & 3) << 6;
  ulProtocol &= 0x00000030;
  ulRegVal = (ulSCR << 8) | ulSPH_SPO | ulProtocol | (ulDataWidth - 1);
  (*((volatile unsigned long *)(ulBase + 0x00000000))) = ulRegVal;
}


x86 assembly (clang, -O0):
<SSIConfigSetExpClk>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <SSIBaseValid@plt>
mov    %eax,%edi
call   1030 <DEBUG_ASSERT@plt>
mov    $0x1,%al
cmpq   $0x0,-0x18(%rbp)
mov    %al,-0x59(%rbp)
je     11ab <SSIConfigSetExpClk+0x8b>
mov    $0x1,%al
cmpq   $0x2,-0x18(%rbp)
mov    %al,-0x59(%rbp)
je     11ab <SSIConfigSetExpClk+0x8b>
mov    $0x1,%al
cmpq   $0x1,-0x18(%rbp)
mov    %al,-0x59(%rbp)
je     11ab <SSIConfigSetExpClk+0x8b>
mov    $0x1,%al
cmpq   $0x3,-0x18(%rbp)
mov    %al,-0x59(%rbp)
je     11ab <SSIConfigSetExpClk+0x8b>
mov    $0x1,%al
cmpq   $0x10,-0x18(%rbp)
mov    %al,-0x59(%rbp)
je     11ab <SSIConfigSetExpClk+0x8b>
cmpq   $0x20,-0x18(%rbp)
sete   %al
mov    %al,-0x59(%rbp)
mov    -0x59(%rbp),%al
and    $0x1,%al
movzbl %al,%edi
call   1030 <DEBUG_ASSERT@plt>
mov    $0x1,%al
cmpq   $0x0,-0x20(%rbp)
mov    %al,-0x5a(%rbp)
je     11e3 <SSIConfigSetExpClk+0xc3>
mov    $0x1,%al
cmpq   $0x1,-0x20(%rbp)
mov    %al,-0x5a(%rbp)
je     11e3 <SSIConfigSetExpClk+0xc3>
cmpq   $0x2,-0x20(%rbp)
sete   %al
mov    %al,-0x5a(%rbp)
mov    -0x5a(%rbp),%al
and    $0x1,%al
movzbl %al,%edi
call   1030 <DEBUG_ASSERT@plt>
cmpq   $0x0,-0x20(%rbp)
jne    1215 <SSIConfigSetExpClk+0xf5>
mov    -0x28(%rbp),%rcx
mov    -0x10(%rbp),%rdx
shr    $0x1,%rdx
mov    $0x1,%al
cmp    %rdx,%rcx
mov    %al,-0x5b(%rbp)
jbe    1251 <SSIConfigSetExpClk+0x131>
xor    %eax,%eax
cmpq   $0x0,-0x20(%rbp)
mov    %al,-0x5c(%rbp)
je     124b <SSIConfigSetExpClk+0x12b>
mov    -0x28(%rbp),%rax
mov    %rax,-0x68(%rbp)
mov    -0x10(%rbp),%rax
mov    $0xc,%ecx
xor    %edx,%edx
div    %rcx
mov    %rax,%rcx
mov    -0x68(%rbp),%rax
cmp    %rcx,%rax
setbe  %al
mov    %al,-0x5c(%rbp)
mov    -0x5c(%rbp),%al
mov    %al,-0x5b(%rbp)
mov    -0x5b(%rbp),%al
and    $0x1,%al
movzbl %al,%edi
call   1030 <DEBUG_ASSERT@plt>
mov    -0x10(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x28(%rbp)
cmp    $0xfe00,%rax
setbe  %al
and    $0x1,%al
movzbl %al,%edi
call   1030 <DEBUG_ASSERT@plt>
xor    %eax,%eax
cmpq   $0x4,-0x30(%rbp)
mov    %al,-0x69(%rbp)
jb     1298 <SSIConfigSetExpClk+0x178>
cmpq   $0x10,-0x30(%rbp)
setbe  %al
mov    %al,-0x69(%rbp)
mov    -0x69(%rbp),%al
and    $0x1,%al
movzbl %al,%edi
call   1030 <DEBUG_ASSERT@plt>
mov    -0x20(%rbp),%rdx
xor    %eax,%eax
mov    $0x8,%ecx
cmp    $0x2,%rdx
cmove  %ecx,%eax
cltq
mov    %rax,-0x40(%rbp)
mov    -0x20(%rbp),%rdx
mov    $0x4,%eax
xor    %ecx,%ecx
cmp    $0x0,%rdx
cmove  %ecx,%eax
cltq
or     -0x40(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rcx
mov    -0x8(%rbp),%rax
mov    %rcx,0x4(%rax)
mov    -0x10(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x28(%rbp)
mov    %rax,-0x38(%rbp)
movq   $0x0,-0x48(%rbp)
mov    -0x48(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x48(%rbp)
mov    -0x38(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x48(%rbp)
sub    $0x1,%rax
mov    %rax,-0x50(%rbp)
cmpq   $0xff,-0x50(%rbp)
ja     12fd <SSIConfigSetExpClk+0x1dd>
mov    -0x48(%rbp),%rcx
mov    -0x8(%rbp),%rax
mov    %rcx,0x10(%rax)
mov    -0x18(%rbp),%rax
and    $0x3,%rax
shl    $0x6,%rax
mov    %rax,-0x58(%rbp)
mov    -0x18(%rbp),%rax
and    $0x30,%rax
mov    %rax,-0x18(%rbp)
mov    -0x50(%rbp),%rax
shl    $0x8,%rax
or     -0x58(%rbp),%rax
or     -0x18(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x1,%rcx
or     %rcx,%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rcx
mov    -0x8(%rbp),%rax
mov    %rcx,(%rax)
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<SSIConfigSetExpClk>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %r9,%r12
mov    %r8,%r13
mov    %rcx,%r15
mov    %rdx,%rbx
mov    %rsi,%rbp
mov    %rdi,0x8(%rsp)
call   1040 <SSIBaseValid@plt>
mov    %eax,%edi
call   1030 <DEBUG_ASSERT@plt>
mov    $0x1,%edi
cmp    $0x4,%rbx
jb     1169 <SSIConfigSetExpClk+0x49>
cmp    $0x10,%rbx
je     1169 <SSIConfigSetExpClk+0x49>
xor    %edi,%edi
cmp    $0x20,%rbx
sete   %dil
mov    %rbx,0x10(%rsp)
call   1030 <DEBUG_ASSERT@plt>
test   %r15,%r15
sete   %r14b
xor    %edi,%edi
cmp    $0x3,%r15
setb   %dil
call   1030 <DEBUG_ASSERT@plt>
mov    %rbp,%rax
shr    %rax
cmp    %r13,%rax
setae  %al
test   %r15,%r15
je     11bc <SSIConfigSetExpClk+0x9c>
movabs $0xaaaaaaaaaaaaaaab,%rcx
aa aa aa
mov    %rbp,%rax
mul    %rcx
shr    $0x3,%rdx
cmp    %r13,%rdx
setae  %r14b
mov    $0x4,%ebx
jmp    11c1 <SSIConfigSetExpClk+0xa1>
and    %al,%r14b
xor    %ebx,%ebx
movzbl %r14b,%edi
call   1030 <DEBUG_ASSERT@plt>
mov    %rbp,%rax
or     %r13,%rax
shr    $0x20,%rax
je     11e8 <SSIConfigSetExpClk+0xc8>
mov    0x8(%rsp),%r14
mov    %rbp,%rax
xor    %edx,%edx
div    %r13
mov    %rax,%rbp
jmp    11f6 <SSIConfigSetExpClk+0xd6>
mov    0x8(%rsp),%r14
mov    %ebp,%eax
xor    %edx,%edx
div    %r13d
mov    %eax,%ebp
mov    %rbx,%r13
xor    %ebx,%ebx
cmp    $0x2,%r15
sete   %bl
xor    %edi,%edi
cmp    $0xfe01,%rbp
setb   %dil
call   1030 <DEBUG_ASSERT@plt>
lea    -0x4(%r12),%rax
xor    %edi,%edi
cmp    $0xd,%rax
setb   %dil
call   1030 <DEBUG_ASSERT@plt>
lea    0x0(,%rbx,8),%rax
add    %r13,%rax
mov    %r14,%rsi
mov    %rax,0x4(%r14)
xor    %ecx,%ecx
mov    0x10(%rsp),%rdi
jmp    1264 <SSIConfigSetExpClk+0x144>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %rbp,%rax
xor    %edx,%edx
div    %rcx
add    $0xffffffffffffffff,%rax
cmp    $0xff,%rax
jbe    127c <SSIConfigSetExpClk+0x15c>
add    $0x2,%rcx
mov    %rbp,%rax
or     %rcx,%rax
shr    $0x20,%rax
jne    1250 <SSIConfigSetExpClk+0x130>
mov    %ebp,%eax
xor    %edx,%edx
div    %ecx
jmp    1258 <SSIConfigSetExpClk+0x138>
mov    %rcx,0x10(%rsi)
mov    %edi,%ecx
shl    $0x6,%ecx
movzbl %cl,%ecx
and    $0x30,%edi
shl    $0x8,%rax
or     %rcx,%rax
or     %rdi,%rax
add    $0xffffffffffffffff,%r12
or     %rax,%r12
mov    %r12,(%rsi)
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @SSIConfigSetExpClk(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) {
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
%12 = alloca i64
%13 = alloca i64
%14 = alloca i64
%15 = alloca i64
%16 = alloca i64
%17 = alloca i64
store i64 %0, i64* %7
store i64 %1, i64* %8
store i64 %2, i64* %9
store i64 %3, i64* %10
store i64 %4, i64* %11
store i64 %5, i64* %12
%18 = load i64, i64* %7
%19 = call i32 @SSIBaseValid(i64 %18)
%20 = call i32 @DEBUG_ASSERT(i32 %19)
%21 = load i64, i64* %9
%22 = icmp eq i64 %21, 0
br i1 %22, label %38, label %23
23: ; preds = %6
%24 = load i64, i64* %9
%25 = icmp eq i64 %24, 2
br i1 %25, label %38, label %26
26: ; preds = %23
%27 = load i64, i64* %9
%28 = icmp eq i64 %27, 1
br i1 %28, label %38, label %29
29: ; preds = %26
%30 = load i64, i64* %9
%31 = icmp eq i64 %30, 3
br i1 %31, label %38, label %32
32: ; preds = %29
%33 = load i64, i64* %9
%34 = icmp eq i64 %33, 16
br i1 %34, label %38, label %35
35: ; preds = %32
%36 = load i64, i64* %9
%37 = icmp eq i64 %36, 32
br label %38
38: ; preds = %35, %32, %29, %26, %23, %6
%39 = phi i1 [ true, %32 ], [ true, %29 ], [ true, %26 ], [ true, %23 ], [ true, %6 ], [ %37, %35 ]
%40 = zext i1 %39 to i32
%41 = call i32 @DEBUG_ASSERT(i32 %40)
%42 = load i64, i64* %10
%43 = icmp eq i64 %42, 0
br i1 %43, label %50, label %44
44: ; preds = %38
%45 = load i64, i64* %10
%46 = icmp eq i64 %45, 1
br i1 %46, label %50, label %47
47: ; preds = %44
%48 = load i64, i64* %10
%49 = icmp eq i64 %48, 2
br label %50
50: ; preds = %47, %44, %38
%51 = phi i1 [ true, %44 ], [ true, %38 ], [ %49, %47 ]
%52 = zext i1 %51 to i32
%53 = call i32 @DEBUG_ASSERT(i32 %52)
%54 = load i64, i64* %10
%55 = icmp eq i64 %54, 0
br i1 %55, label %56, label %61
56: ; preds = %50
%57 = load i64, i64* %11
%58 = load i64, i64* %8
%59 = udiv i64 %58, 2
%60 = icmp ule i64 %57, %59
br i1 %60, label %71, label %61
61: ; preds = %56, %50
%62 = load i64, i64* %10
%63 = icmp ne i64 %62, 0
br i1 %63, label %64, label %69
64: ; preds = %61
%65 = load i64, i64* %11
%66 = load i64, i64* %8
%67 = udiv i64 %66, 12
%68 = icmp ule i64 %65, %67
br label %69
69: ; preds = %64, %61
%70 = phi i1 [ false, %61 ], [ %68, %64 ]
br label %71
71: ; preds = %69, %56
%72 = phi i1 [ true, %56 ], [ %70, %69 ]
%73 = zext i1 %72 to i32
%74 = call i32 @DEBUG_ASSERT(i32 %73)
%75 = load i64, i64* %8
%76 = load i64, i64* %11
%77 = udiv i64 %75, %76
%78 = icmp ule i64 %77, 65024
%79 = zext i1 %78 to i32
%80 = call i32 @DEBUG_ASSERT(i32 %79)
%81 = load i64, i64* %12
%82 = icmp uge i64 %81, 4
br i1 %82, label %83, label %86
83: ; preds = %71
%84 = load i64, i64* %12
%85 = icmp ule i64 %84, 16
br label %86
86: ; preds = %83, %71
%87 = phi i1 [ false, %71 ], [ %85, %83 ]
%88 = zext i1 %87 to i32
%89 = call i32 @DEBUG_ASSERT(i32 %88)
%90 = load i64, i64* %10
%91 = icmp eq i64 %90, 2
%92 = zext i1 %91 to i64
%93 = select i1 %91, i32 8, i32 0
%94 = sext i32 %93 to i64
store i64 %94, i64* %14
%95 = load i64, i64* %10
%96 = icmp eq i64 %95, 0
%97 = zext i1 %96 to i64
%98 = select i1 %96, i32 0, i32 4
%99 = sext i32 %98 to i64
%100 = load i64, i64* %14
%101 = or i64 %100, %99
store i64 %101, i64* %14
%102 = load i64, i64* %14
%103 = load i64, i64* %7
%104 = add i64 %103, 4
%105 = inttoptr i64 %104 to i64*
store volatile i64 %102, i64* %105
%106 = load i64, i64* %8
%107 = load i64, i64* %11
%108 = udiv i64 %106, %107
store i64 %108, i64* %13
store i64 0, i64* %15
br label %109
109: ; preds = %116, %86
%110 = load i64, i64* %15
%111 = add i64 %110, 2
store i64 %111, i64* %15
%112 = load i64, i64* %13
%113 = load i64, i64* %15
%114 = udiv i64 %112, %113
%115 = sub i64 %114, 1
store i64 %115, i64* %16
br label %116
116: ; preds = %109
%117 = load i64, i64* %16
%118 = icmp ugt i64 %117, 255
br i1 %118, label %109, label %119
119: ; preds = %116
%120 = load i64, i64* %15
%121 = load i64, i64* %7
%122 = add i64 %121, 16
%123 = inttoptr i64 %122 to i64*
store volatile i64 %120, i64* %123
%124 = load i64, i64* %9
%125 = and i64 %124, 3
%126 = shl i64 %125, 6
store i64 %126, i64* %17
%127 = load i64, i64* %9
%128 = and i64 %127, 48
store i64 %128, i64* %9
%129 = load i64, i64* %16
%130 = shl i64 %129, 8
%131 = load i64, i64* %17
%132 = or i64 %130, %131
%133 = load i64, i64* %9
%134 = or i64 %132, %133
%135 = load i64, i64* %12
%136 = sub i64 %135, 1
%137 = or i64 %134, %136
store i64 %137, i64* %14
%138 = load i64, i64* %14
%139 = load i64, i64* %7
%140 = add i64 %139, 0
%141 = inttoptr i64 %140 to i64*
store volatile i64 %138, i64* %141
ret void
}

LLVM IR (-O2):
define void @SSIConfigSetExpClk(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) {
%7 = tail call i32 @SSIBaseValid(i64 %0)
%8 = tail call i32 @DEBUG_ASSERT(i32 %7)
switch i64 %2, label %9 [
i64 16, label %12
i64 3, label %12
i64 2, label %12
i64 1, label %12
i64 0, label %12
]
9: ; preds = %6
%10 = icmp eq i64 %2, 32
%11 = zext i1 %10 to i32
br label %12
12: ; preds = %6, %6, %6, %6, %6, %9
%13 = phi i32 [ 1, %6 ], [ %11, %9 ], [ 1, %6 ], [ 1, %6 ], [ 1, %6 ], [ 1, %6 ]
%14 = tail call i32 @DEBUG_ASSERT(i32 %13)
%15 = icmp eq i64 %3, 0
%16 = icmp eq i64 %3, 2
%17 = icmp ult i64 %3, 3
%18 = zext i1 %17 to i32
%19 = tail call i32 @DEBUG_ASSERT(i32 %18)
%20 = lshr i64 %1, 1
%21 = icmp uge i64 %20, %4
%22 = and i1 %15, %21
br i1 %15, label %26, label %23
23: ; preds = %12
%24 = udiv i64 %1, 12
%25 = icmp uge i64 %24, %4
br label %26
26: ; preds = %12, %23
%27 = phi i64 [ 0, %12 ], [ 4, %23 ]
%28 = phi i1 [ %22, %12 ], [ %25, %23 ]
%29 = zext i1 %28 to i32
%30 = tail call i32 @DEBUG_ASSERT(i32 %29)
%31 = udiv i64 %1, %4
%32 = icmp ult i64 %31, 65025
%33 = zext i1 %32 to i32
%34 = tail call i32 @DEBUG_ASSERT(i32 %33)
%35 = add i64 %5, -4
%36 = icmp ult i64 %35, 13
%37 = zext i1 %36 to i32
%38 = tail call i32 @DEBUG_ASSERT(i32 %37)
%39 = select i1 %16, i64 8, i64 0
%40 = or i64 %27, %39
%41 = add i64 %0, 4
%42 = inttoptr i64 %41 to i64*
store volatile i64 %40, i64* %42
br label %43
43: ; preds = %43, %26
%44 = phi i64 [ 0, %26 ], [ %45, %43 ]
%45 = add i64 %44, 2
%46 = udiv i64 %31, %45
%47 = add i64 %46, -1
%48 = icmp ugt i64 %47, 255
br i1 %48, label %43, label %49
49: ; preds = %43
%50 = add i64 %0, 16
%51 = inttoptr i64 %50 to i64*
store volatile i64 %45, i64* %51
%52 = shl i64 %2, 6
%53 = and i64 %52, 192
%54 = and i64 %2, 48
%55 = shl nuw nsw i64 %47, 8
%56 = or i64 %55, %53
%57 = or i64 %56, %54
%58 = add i64 %5, -1
%59 = or i64 %57, %58
%60 = inttoptr i64 %0 to i64*
store volatile i64 %59, i64* %60
ret void
}