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 + (ulEndpoint - 0x10) + 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    116f <USBHostEndpointConfig+0x6f>
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    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cl,0x10a(%rax)
jmp    13fa <USBHostEndpointConfig+0x2fa>
mov    -0x28(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x1000,%rax
cmp    $0x0,%rax
je     119e <USBHostEndpointConfig+0x9e>
mov    -0x38(%rbp),%rax
or     $0x80,%rax
mov    %rax,-0x38(%rbp)
jmp    11ac <USBHostEndpointConfig+0xac>
mov    -0x38(%rbp),%rax
or     $0xc0,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x300,%rax
mov    %rax,-0x40(%rbp)
je     1215 <USBHostEndpointConfig+0x115>
jmp    11c5 <USBHostEndpointConfig+0xc5>
mov    -0x40(%rbp),%rax
sub    $0x100,%rax
je     1204 <USBHostEndpointConfig+0x104>
jmp    11da <USBHostEndpointConfig+0xda>
mov    -0x40(%rbp),%rax
sub    $0x200,%rax
je     1226 <USBHostEndpointConfig+0x126>
jmp    11ef <USBHostEndpointConfig+0xef>
mov    -0x40(%rbp),%rax
sub    $0x300,%rax
je     1237 <USBHostEndpointConfig+0x137>
jmp    1243 <USBHostEndpointConfig+0x143>
mov    -0x38(%rbp),%rax
or     $0x20,%rax
mov    %rax,-0x38(%rbp)
jmp    1243 <USBHostEndpointConfig+0x143>
mov    -0x38(%rbp),%rax
or     $0x10,%rax
mov    %rax,-0x38(%rbp)
jmp    1243 <USBHostEndpointConfig+0x143>
mov    -0x38(%rbp),%rax
or     $0x30,%rax
mov    %rax,-0x38(%rbp)
jmp    1243 <USBHostEndpointConfig+0x143>
mov    -0x38(%rbp),%rax
or     $0x0,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x2000,%rax
cmp    $0x0,%rax
je     1336 <USBHostEndpointConfig+0x236>
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     12d0 <USBHostEndpointConfig+0x1d0>
mov    -0x38(%rbp),%rax
or     $0x80,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x10,%rax
cmp    $0x0,%rax
je     12f3 <USBHostEndpointConfig+0x1f3>
mov    -0x38(%rbp),%rax
or     $0x14,%rax
mov    %rax,-0x38(%rbp)
jmp    1316 <USBHostEndpointConfig+0x216>
mov    -0x30(%rbp),%rax
and    $0x8,%rax
cmp    $0x0,%rax
je     1311 <USBHostEndpointConfig+0x211>
mov    -0x38(%rbp),%rax
or     $0x10,%rax
mov    %rax,-0x38(%rbp)
jmp    1316 <USBHostEndpointConfig+0x216>
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    13f5 <USBHostEndpointConfig+0x2f5>
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     1394 <USBHostEndpointConfig+0x294>
mov    -0x38(%rbp),%rax
or     $0x80,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x10,%rax
cmp    $0x0,%rax
je     13b7 <USBHostEndpointConfig+0x2b7>
mov    -0x38(%rbp),%rax
or     $0x28,%rax
mov    %rax,-0x38(%rbp)
jmp    13da <USBHostEndpointConfig+0x2da>
mov    -0x30(%rbp),%rax
and    $0x8,%rax
cmp    $0x0,%rax
je     13d5 <USBHostEndpointConfig+0x2d5>
mov    -0x38(%rbp),%rax
or     $0x20,%rax
mov    %rax,-0x38(%rbp)
jmp    13da <USBHostEndpointConfig+0x2da>
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    13fa <USBHostEndpointConfig+0x2fa>
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    $0xfa,%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 %34
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 = load i64, i64* %8
%30 = sub i64 %29, 16
%31 = add i64 %28, %30
%32 = add i64 %31, 266
%33 = inttoptr i64 %32 to i8*
store volatile i8 %27, i8* %33
br label %167
34: ; preds = %6
%35 = load i64, i64* %11
store i64 %35, i64* %13
%36 = load i64, i64* %12
%37 = and i64 %36, 4096
%38 = icmp ne i64 %37, 0
br i1 %38, label %39, label %42
39: ; preds = %34
%40 = load i64, i64* %13
%41 = or i64 %40, 128
store i64 %41, i64* %13
br label %45
42: ; preds = %34
%43 = load i64, i64* %13
%44 = or i64 %43, 192
store i64 %44, i64* %13
br label %45
45: ; preds = %42, %39
%46 = load i64, i64* %12
%47 = and i64 %46, 768
switch i64 %47, label %60 [
i64 256, label %48
i64 0, label %51
i64 512, label %54
i64 768, label %57
]
48: ; preds = %45
%49 = load i64, i64* %13
%50 = or i64 %49, 32
store i64 %50, i64* %13
br label %60
51: ; preds = %45
%52 = load i64, i64* %13
%53 = or i64 %52, 16
store i64 %53, i64* %13
br label %60
54: ; preds = %45
%55 = load i64, i64* %13
%56 = or i64 %55, 48
store i64 %56, i64* %13
br label %60
57: ; preds = %45
%58 = load i64, i64* %13
%59 = or i64 %58, 0
store i64 %59, i64* %13
br label %60
60: ; preds = %45, %57, %54, %51, %48
%61 = load i64, i64* %12
%62 = and i64 %61, 8192
%63 = icmp ne i64 %62, 0
br i1 %63, label %64, label %119
64: ; preds = %60
%65 = load i64, i64* %13
%66 = trunc i64 %65 to i8
%67 = load i64, i64* %7
%68 = load i64, i64* %8
%69 = sub i64 %68, 16
%70 = add i64 %67, %69
%71 = add i64 %70, 282
%72 = inttoptr i64 %71 to i8*
store volatile i8 %66, i8* %72
%73 = load i64, i64* %10
%74 = trunc i64 %73 to i8
%75 = load i64, i64* %7
%76 = load i64, i64* %8
%77 = sub i64 %76, 16
%78 = add i64 %75, %77
%79 = add i64 %78, 283
%80 = inttoptr i64 %79 to i8*
store volatile i8 %74, i8* %80
%81 = load i64, i64* %9
%82 = trunc i64 %81 to i8
%83 = load i64, i64* %7
%84 = load i64, i64* %8
%85 = sub i64 %84, 16
%86 = add i64 %83, %85
%87 = add i64 %86, 272
%88 = inttoptr i64 %87 to i8*
store volatile i8 %82, i8* %88
store i64 0, i64* %13
%89 = load i64, i64* %12
%90 = and i64 %89, 1
%91 = icmp ne i64 %90, 0
br i1 %91, label %92, label %95
92: ; preds = %64
%93 = load i64, i64* %13
%94 = or i64 %93, 128
store i64 %94, i64* %13
br label %95
95: ; preds = %92, %64
%96 = load i64, i64* %12
%97 = and i64 %96, 16
%98 = icmp ne i64 %97, 0
br i1 %98, label %99, label %102
99: ; preds = %95
%100 = load i64, i64* %13
%101 = or i64 %100, 20
store i64 %101, i64* %13
br label %110
102: ; preds = %95
%103 = load i64, i64* %12
%104 = and i64 %103, 8
%105 = icmp ne i64 %104, 0
br i1 %105, label %106, label %109
106: ; preds = %102
%107 = load i64, i64* %13
%108 = or i64 %107, 16
store i64 %108, i64* %13
br label %109
109: ; preds = %106, %102
br label %110
110: ; preds = %109, %99
%111 = load i64, i64* %13
%112 = trunc i64 %111 to i8
%113 = load i64, i64* %7
%114 = load i64, i64* %8
%115 = sub i64 %114, 16
%116 = add i64 %113, %115
%117 = add i64 %116, 275
%118 = inttoptr i64 %117 to i8*
store volatile i8 %112, i8* %118
br label %166
119: ; preds = %60
%120 = load i64, i64* %13
%121 = trunc i64 %120 to i8
%122 = load i64, i64* %7
%123 = load i64, i64* %8
%124 = sub i64 %123, 16
%125 = add i64 %122, %124
%126 = add i64 %125, 284
%127 = inttoptr i64 %126 to i8*
store volatile i8 %121, i8* %127
%128 = load i64, i64* %10
%129 = trunc i64 %128 to i8
%130 = load i64, i64* %7
%131 = load i64, i64* %8
%132 = sub i64 %131, 16
%133 = add i64 %130, %132
%134 = add i64 %133, 285
%135 = inttoptr i64 %134 to i8*
store volatile i8 %129, i8* %135
store i64 0, i64* %13
%136 = load i64, i64* %12
%137 = and i64 %136, 4
%138 = icmp ne i64 %137, 0
br i1 %138, label %139, label %142
139: ; preds = %119
%140 = load i64, i64* %13
%141 = or i64 %140, 128
store i64 %141, i64* %13
br label %142
142: ; preds = %139, %119
%143 = load i64, i64* %12
%144 = and i64 %143, 16
%145 = icmp ne i64 %144, 0
br i1 %145, label %146, label %149
146: ; preds = %142
%147 = load i64, i64* %13
%148 = or i64 %147, 40
store i64 %148, i64* %13
br label %157
149: ; preds = %142
%150 = load i64, i64* %12
%151 = and i64 %150, 8
%152 = icmp ne i64 %151, 0
br i1 %152, label %153, label %156
153: ; preds = %149
%154 = load i64, i64* %13
%155 = or i64 %154, 32
store i64 %155, i64* %13
br label %156
156: ; preds = %153, %149
br label %157
157: ; preds = %156, %146
%158 = load i64, i64* %13
%159 = trunc i64 %158 to i8
%160 = load i64, i64* %7
%161 = load i64, i64* %8
%162 = sub i64 %161, 16
%163 = add i64 %160, %162
%164 = add i64 %163, 279
%165 = inttoptr i64 %164 to i8*
store volatile i8 %159, i8* %165
br label %166
166: ; preds = %157, %110
br label %167
167: ; preds = %166, %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, 250
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
}