void USBHostEndpointConfig(unsigned long ulBase, unsigned long ulEndpoint,
                           unsigned long ulMaxPayload,
                           unsigned long ulNAKPollInterval,
                           unsigned long ulTargetEndpoint,
                           unsigned long ulFlags) {
  unsigned long ulRegister;
  ;

  ;
  ;
  if (ulEndpoint == 0x00000000) {
    (*((volatile unsigned char *)(ulBase + 0x0000010B))) = ulNAKPollInterval;
    (*((volatile unsigned char *)(ulBase + 0x0000010A))) =
        ((ulFlags & 0x00001000) ? 0x00000080 : 0x000000C0);
  } else {
    ulRegister = ulTargetEndpoint;
    if (ulFlags & 0x00001000) {
      ulRegister |= 0x00000080;
    } else {
      ulRegister |= 0x000000C0;
    }
    switch (ulFlags & 0x00000300) {
    case 0x00000100: {
      ulRegister |= 0x00000020;
      break;
    }
    case 0x00000000: {
      ulRegister |= 0x00000010;
      break;
    }
    case 0x00000200: {
      ulRegister |= 0x00000030;
      break;
    }
    case 0x00000300: {
      ulRegister |= 0x00000000;
      break;
    }
    }
    if (ulFlags & 0x00002000) {
      (*((volatile unsigned char *)(ulBase + (ulEndpoint - 0x10) +
                                    0x0000011A))) = ulRegister;
      (*((volatile unsigned char *)(ulBase + (ulEndpoint - 0x10) +
                                    0x0000011B))) = ulNAKPollInterval;
      (*((volatile unsigned char *)(ulBase + (ulEndpoint - 0x10) +
                                    0x00000110))) = ulMaxPayload;
      ulRegister = 0;
      if (ulFlags & 0x00000001) {
        ulRegister |= 0x00000080;
      }
      if (ulFlags & 0x00000010) {
        ulRegister |= 0x00000010 | 0x00000004;
      } else if (ulFlags & 0x00000008) {
        ulRegister |= 0x00000010;
      }
      (*((volatile unsigned char *)(ulBase + (ulEndpoint - 0x10) +
                                    0x00000113))) = (unsigned char)ulRegister;
    } else {
      (*((volatile unsigned char *)(ulBase + (ulEndpoint - 0x10) +
                                    0x0000011C))) = ulRegister;
      (*((volatile unsigned char *)(ulBase + (ulEndpoint - 0x10) +
                                    0x0000011D))) = ulNAKPollInterval;
      ulRegister = 0;
      if (ulFlags & 0x00000004) {
        ulRegister |= 0x00000080;
      }
      if (ulFlags & 0x00000010) {
        ulRegister |= 0x00000020 | 0x00000008;
      } else if (ulFlags & 0x00000008) {
        ulRegister |= 0x00000020;
      }
      (*((volatile unsigned char *)(ulBase + (ulEndpoint - 0x10) +
                                    0x00000117))) = (unsigned char)ulRegister;
    }
  }
}


x86 assembly (clang, -O0):
<USBHostEndpointConfig>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1164 <USBHostEndpointConfig+0x64>
mov    -0x20(%rbp),%rax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,0x10b(%rax)
mov    -0x30(%rbp),%rdx
and    $0x1000,%rdx
mov    $0xc0,%eax
mov    $0x80,%ecx
cmp    $0x0,%rdx
cmovne %ecx,%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,0x10a(%rax)
jmp    13ef <USBHostEndpointConfig+0x2ef>
mov    -0x28(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x1000,%rax
cmp    $0x0,%rax
je     1193 <USBHostEndpointConfig+0x93>
mov    -0x38(%rbp),%rax
or     $0x80,%rax
mov    %rax,-0x38(%rbp)
jmp    11a1 <USBHostEndpointConfig+0xa1>
mov    -0x38(%rbp),%rax
or     $0xc0,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x300,%rax
mov    %rax,-0x40(%rbp)
je     120a <USBHostEndpointConfig+0x10a>
jmp    11ba <USBHostEndpointConfig+0xba>
mov    -0x40(%rbp),%rax
sub    $0x100,%rax
je     11f9 <USBHostEndpointConfig+0xf9>
jmp    11cf <USBHostEndpointConfig+0xcf>
mov    -0x40(%rbp),%rax
sub    $0x200,%rax
je     121b <USBHostEndpointConfig+0x11b>
jmp    11e4 <USBHostEndpointConfig+0xe4>
mov    -0x40(%rbp),%rax
sub    $0x300,%rax
je     122c <USBHostEndpointConfig+0x12c>
jmp    1238 <USBHostEndpointConfig+0x138>
mov    -0x38(%rbp),%rax
or     $0x20,%rax
mov    %rax,-0x38(%rbp)
jmp    1238 <USBHostEndpointConfig+0x138>
mov    -0x38(%rbp),%rax
or     $0x10,%rax
mov    %rax,-0x38(%rbp)
jmp    1238 <USBHostEndpointConfig+0x138>
mov    -0x38(%rbp),%rax
or     $0x30,%rax
mov    %rax,-0x38(%rbp)
jmp    1238 <USBHostEndpointConfig+0x138>
mov    -0x38(%rbp),%rax
or     $0x0,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x2000,%rax
cmp    $0x0,%rax
je     132b <USBHostEndpointConfig+0x22b>
mov    -0x38(%rbp),%rax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cl,0x11a(%rax)
mov    -0x20(%rbp),%rax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cl,0x11b(%rax)
mov    -0x18(%rbp),%rax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cl,0x110(%rax)
movq   $0x0,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x1,%rax
cmp    $0x0,%rax
je     12c5 <USBHostEndpointConfig+0x1c5>
mov    -0x38(%rbp),%rax
or     $0x80,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x10,%rax
cmp    $0x0,%rax
je     12e8 <USBHostEndpointConfig+0x1e8>
mov    -0x38(%rbp),%rax
or     $0x14,%rax
mov    %rax,-0x38(%rbp)
jmp    130b <USBHostEndpointConfig+0x20b>
mov    -0x30(%rbp),%rax
and    $0x8,%rax
cmp    $0x0,%rax
je     1306 <USBHostEndpointConfig+0x206>
mov    -0x38(%rbp),%rax
or     $0x10,%rax
mov    %rax,-0x38(%rbp)
jmp    130b <USBHostEndpointConfig+0x20b>
mov    -0x38(%rbp),%rax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cl,0x113(%rax)
jmp    13ea <USBHostEndpointConfig+0x2ea>
mov    -0x38(%rbp),%rax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cl,0x11c(%rax)
mov    -0x20(%rbp),%rax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cl,0x11d(%rax)
movq   $0x0,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x4,%rax
cmp    $0x0,%rax
je     1389 <USBHostEndpointConfig+0x289>
mov    -0x38(%rbp),%rax
or     $0x80,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x10,%rax
cmp    $0x0,%rax
je     13ac <USBHostEndpointConfig+0x2ac>
mov    -0x38(%rbp),%rax
or     $0x28,%rax
mov    %rax,-0x38(%rbp)
jmp    13cf <USBHostEndpointConfig+0x2cf>
mov    -0x30(%rbp),%rax
and    $0x8,%rax
cmp    $0x0,%rax
je     13ca <USBHostEndpointConfig+0x2ca>
mov    -0x38(%rbp),%rax
or     $0x20,%rax
mov    %rax,-0x38(%rbp)
jmp    13cf <USBHostEndpointConfig+0x2cf>
mov    -0x38(%rbp),%rax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cl,0x117(%rax)
jmp    13ef <USBHostEndpointConfig+0x2ef>
pop    %rbp
ret

x86 assembly (clang, -O2):
<USBHostEndpointConfig>:
test   %rsi,%rsi
je     1140 <USBHostEndpointConfig+0x40>
xor    %r10d,%r10d
test   $0x1000,%r9d
sete   %r10b
shl    $0x6,%r10
or     %r8,%r10
or     $0x80,%r10
mov    %r9d,%eax
shr    $0x8,%eax
and    $0x3,%eax
lea    0xecf(%rip),%r8
movslq (%r8,%rax,4),%rax
add    %r8,%rax
jmp    *%rax
or     $0x10,%r10
jmp    1169 <USBHostEndpointConfig+0x69>
mov    %cl,0x10b(%rdi)
test   $0x1000,%r9d
sete   %al
shl    $0x6,%al
or     $0x80,%al
add    $0x10a,%rdi
mov    %al,(%rdi)
ret
or     $0x20,%r10
jmp    1169 <USBHostEndpointConfig+0x69>
or     $0x30,%r10
add    %rsi,%rdi
add    $0xfffffffffffffff0,%rdi
test   $0x2000,%r9d
jne    11b2 <USBHostEndpointConfig+0xb2>
mov    %r10b,0x11c(%rdi)
mov    %cl,0x11d(%rdi)
mov    %r9d,%ecx
and    $0x4,%ecx
shl    $0x5,%ecx
lea    0x0(,%r9,4),%edx
and    $0x20,%edx
test   $0x10,%r9b
mov    $0x28,%eax
cmove  %edx,%eax
or     %ecx,%eax
add    $0x117,%rdi
mov    %al,(%rdi)
ret
mov    %r10b,0x11a(%rdi)
mov    %cl,0x11b(%rdi)
mov    %dl,0x110(%rdi)
test   $0x10,%r9b
jne    11e6 <USBHostEndpointConfig+0xe6>
rol    $0x4,%r9b
mov    %r9d,%eax
shr    $0x3,%al
shl    $0x3,%r9b
and    $0x80,%r9b
or     %al,%r9b
and    $0x90,%r9b
jmp    11ee <USBHostEndpointConfig+0xee>
shl    $0x7,%r9d
or     $0x14,%r9d
movzbl %r9b,%eax
add    $0x113,%rdi
mov    %al,(%rdi)
ret

LLVM IR (-O0):
define void @USBHostEndpointConfig(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
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
%14 = load i64, i64* %8
%15 = icmp eq i64 %14, 0
br i1 %15, label %16, label %31
16: ; preds = %6
%17 = load i64, i64* %10
%18 = trunc i64 %17 to i8
%19 = load i64, i64* %7
%20 = add i64 %19, 267
%21 = inttoptr i64 %20 to i8*
store volatile i8 %18, i8* %21
%22 = load i64, i64* %12
%23 = and i64 %22, 4096
%24 = icmp ne i64 %23, 0
%25 = zext i1 %24 to i64
%26 = select i1 %24, i32 128, i32 192
%27 = trunc i32 %26 to i8
%28 = load i64, i64* %7
%29 = add i64 %28, 266
%30 = inttoptr i64 %29 to i8*
store volatile i8 %27, i8* %30
br label %164
31: ; preds = %6
%32 = load i64, i64* %11
store i64 %32, i64* %13
%33 = load i64, i64* %12
%34 = and i64 %33, 4096
%35 = icmp ne i64 %34, 0
br i1 %35, label %36, label %39
36: ; preds = %31
%37 = load i64, i64* %13
%38 = or i64 %37, 128
store i64 %38, i64* %13
br label %42
39: ; preds = %31
%40 = load i64, i64* %13
%41 = or i64 %40, 192
store i64 %41, i64* %13
br label %42
42: ; preds = %39, %36
%43 = load i64, i64* %12
%44 = and i64 %43, 768
switch i64 %44, label %57 [
i64 256, label %45
i64 0, label %48
i64 512, label %51
i64 768, label %54
]
45: ; preds = %42
%46 = load i64, i64* %13
%47 = or i64 %46, 32
store i64 %47, i64* %13
br label %57
48: ; preds = %42
%49 = load i64, i64* %13
%50 = or i64 %49, 16
store i64 %50, i64* %13
br label %57
51: ; preds = %42
%52 = load i64, i64* %13
%53 = or i64 %52, 48
store i64 %53, i64* %13
br label %57
54: ; preds = %42
%55 = load i64, i64* %13
%56 = or i64 %55, 0
store i64 %56, i64* %13
br label %57
57: ; preds = %42, %54, %51, %48, %45
%58 = load i64, i64* %12
%59 = and i64 %58, 8192
%60 = icmp ne i64 %59, 0
br i1 %60, label %61, label %116
61: ; preds = %57
%62 = load i64, i64* %13
%63 = trunc i64 %62 to i8
%64 = load i64, i64* %7
%65 = load i64, i64* %8
%66 = sub i64 %65, 16
%67 = add i64 %64, %66
%68 = add i64 %67, 282
%69 = inttoptr i64 %68 to i8*
store volatile i8 %63, i8* %69
%70 = load i64, i64* %10
%71 = trunc i64 %70 to i8
%72 = load i64, i64* %7
%73 = load i64, i64* %8
%74 = sub i64 %73, 16
%75 = add i64 %72, %74
%76 = add i64 %75, 283
%77 = inttoptr i64 %76 to i8*
store volatile i8 %71, i8* %77
%78 = load i64, i64* %9
%79 = trunc i64 %78 to i8
%80 = load i64, i64* %7
%81 = load i64, i64* %8
%82 = sub i64 %81, 16
%83 = add i64 %80, %82
%84 = add i64 %83, 272
%85 = inttoptr i64 %84 to i8*
store volatile i8 %79, i8* %85
store i64 0, i64* %13
%86 = load i64, i64* %12
%87 = and i64 %86, 1
%88 = icmp ne i64 %87, 0
br i1 %88, label %89, label %92
89: ; preds = %61
%90 = load i64, i64* %13
%91 = or i64 %90, 128
store i64 %91, i64* %13
br label %92
92: ; preds = %89, %61
%93 = load i64, i64* %12
%94 = and i64 %93, 16
%95 = icmp ne i64 %94, 0
br i1 %95, label %96, label %99
96: ; preds = %92
%97 = load i64, i64* %13
%98 = or i64 %97, 20
store i64 %98, i64* %13
br label %107
99: ; preds = %92
%100 = load i64, i64* %12
%101 = and i64 %100, 8
%102 = icmp ne i64 %101, 0
br i1 %102, label %103, label %106
103: ; preds = %99
%104 = load i64, i64* %13
%105 = or i64 %104, 16
store i64 %105, i64* %13
br label %106
106: ; preds = %103, %99
br label %107
107: ; preds = %106, %96
%108 = load i64, i64* %13
%109 = trunc i64 %108 to i8
%110 = load i64, i64* %7
%111 = load i64, i64* %8
%112 = sub i64 %111, 16
%113 = add i64 %110, %112
%114 = add i64 %113, 275
%115 = inttoptr i64 %114 to i8*
store volatile i8 %109, i8* %115
br label %163
116: ; preds = %57
%117 = load i64, i64* %13
%118 = trunc i64 %117 to i8
%119 = load i64, i64* %7
%120 = load i64, i64* %8
%121 = sub i64 %120, 16
%122 = add i64 %119, %121
%123 = add i64 %122, 284
%124 = inttoptr i64 %123 to i8*
store volatile i8 %118, i8* %124
%125 = load i64, i64* %10
%126 = trunc i64 %125 to i8
%127 = load i64, i64* %7
%128 = load i64, i64* %8
%129 = sub i64 %128, 16
%130 = add i64 %127, %129
%131 = add i64 %130, 285
%132 = inttoptr i64 %131 to i8*
store volatile i8 %126, i8* %132
store i64 0, i64* %13
%133 = load i64, i64* %12
%134 = and i64 %133, 4
%135 = icmp ne i64 %134, 0
br i1 %135, label %136, label %139
136: ; preds = %116
%137 = load i64, i64* %13
%138 = or i64 %137, 128
store i64 %138, i64* %13
br label %139
139: ; preds = %136, %116
%140 = load i64, i64* %12
%141 = and i64 %140, 16
%142 = icmp ne i64 %141, 0
br i1 %142, label %143, label %146
143: ; preds = %139
%144 = load i64, i64* %13
%145 = or i64 %144, 40
store i64 %145, i64* %13
br label %154
146: ; preds = %139
%147 = load i64, i64* %12
%148 = and i64 %147, 8
%149 = icmp ne i64 %148, 0
br i1 %149, label %150, label %153
150: ; preds = %146
%151 = load i64, i64* %13
%152 = or i64 %151, 32
store i64 %152, i64* %13
br label %153
153: ; preds = %150, %146
br label %154
154: ; preds = %153, %143
%155 = load i64, i64* %13
%156 = trunc i64 %155 to i8
%157 = load i64, i64* %7
%158 = load i64, i64* %8
%159 = sub i64 %158, 16
%160 = add i64 %157, %159
%161 = add i64 %160, 279
%162 = inttoptr i64 %161 to i8*
store volatile i8 %156, i8* %162
br label %163
163: ; preds = %154, %107
br label %164
164: ; preds = %163, %16
ret void
}

LLVM IR (-O2):
define void @USBHostEndpointConfig(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) {
%7 = icmp eq i64 %1, 0
br i1 %7, label %8, label %16
8: ; preds = %6
%9 = trunc i64 %3 to i8
%10 = add i64 %0, 267
%11 = inttoptr i64 %10 to i8*
store volatile i8 %9, i8* %11
%12 = and i64 %5, 4096
%13 = icmp eq i64 %12, 0
%14 = select i1 %13, i8 -64, i8 -128
%15 = add i64 %0, 266
br label %77
16: ; preds = %6
%17 = and i64 %5, 4096
%18 = icmp eq i64 %17, 0
%19 = select i1 %18, i64 192, i64 128
%20 = or i64 %19, %4
%21 = lshr i64 %5, 8
%22 = and i64 %21, 3
switch i64 %22, label %29 [
i64 1, label %23
i64 0, label %25
i64 2, label %27
i64 3, label %30
]
23: ; preds = %16
%24 = or i64 %20, 32
br label %30
25: ; preds = %16
%26 = or i64 %20, 16
br label %30
27: ; preds = %16
%28 = or i64 %20, 48
br label %30
29: ; preds = %16
unreachable
30: ; preds = %16, %27, %25, %23
%31 = phi i64 [ %28, %27 ], [ %26, %25 ], [ %24, %23 ], [ %20, %16 ]
%32 = and i64 %5, 8192
%33 = icmp eq i64 %32, 0
%34 = trunc i64 %31 to i8
%35 = add i64 %0, -16
%36 = add i64 %35, %1
br i1 %33, label %61, label %37
37: ; preds = %30
%38 = add i64 %36, 282
%39 = inttoptr i64 %38 to i8*
store volatile i8 %34, i8* %39
%40 = trunc i64 %3 to i8
%41 = add i64 %36, 283
%42 = inttoptr i64 %41 to i8*
store volatile i8 %40, i8* %42
%43 = trunc i64 %2 to i8
%44 = add i64 %36, 272
%45 = inttoptr i64 %44 to i8*
store volatile i8 %43, i8* %45
%46 = and i64 %5, 16
%47 = icmp eq i64 %46, 0
br i1 %47, label %52, label %48
48: ; preds = %37
%49 = shl i64 %5, 7
%50 = and i64 %49, 128
%51 = or i64 %50, 20
br label %57
52: ; preds = %37
%53 = trunc i64 %5 to i8
%54 = tail call i8 @llvm.bitreverse.i8(i8 %53)
%55 = and i8 %54, -112
%56 = zext i8 %55 to i64
br label %57
57: ; preds = %52, %48
%58 = phi i64 [ %51, %48 ], [ %56, %52 ]
%59 = trunc i64 %58 to i8
%60 = add i64 %36, 275
br label %77
61: ; preds = %30
%62 = add i64 %36, 284
%63 = inttoptr i64 %62 to i8*
store volatile i8 %34, i8* %63
%64 = trunc i64 %3 to i8
%65 = add i64 %36, 285
%66 = inttoptr i64 %65 to i8*
store volatile i8 %64, i8* %66
%67 = shl i64 %5, 5
%68 = and i64 %67, 128
%69 = and i64 %5, 16
%70 = icmp eq i64 %69, 0
%71 = shl i64 %5, 2
%72 = and i64 %71, 32
%73 = select i1 %70, i64 %72, i64 40
%74 = or i64 %68, %73
%75 = trunc i64 %74 to i8
%76 = add i64 %36, 279
br label %77
77: ; preds = %57, %61, %8
%78 = phi i64 [ %60, %57 ], [ %76, %61 ], [ %15, %8 ]
%79 = phi i8 [ %59, %57 ], [ %75, %61 ], [ %14, %8 ]
%80 = inttoptr i64 %78 to i8*
store volatile i8 %79, i8* %80
ret void
}