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 short *)(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;
      (*((volatile unsigned short *)(ulBase + (ulEndpoint - 0x10) +
                                     0x00000114))) = ulMaxPayload;
      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    140e <USBHostEndpointConfig+0x30e>
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     132d <USBHostEndpointConfig+0x22d>
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    %ax,%cx
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cx,0x110(%rax)
movq   $0x0,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x1,%rax
cmp    $0x0,%rax
je     12c7 <USBHostEndpointConfig+0x1c7>
mov    -0x38(%rbp),%rax
or     $0x80,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x10,%rax
cmp    $0x0,%rax
je     12ea <USBHostEndpointConfig+0x1ea>
mov    -0x38(%rbp),%rax
or     $0x14,%rax
mov    %rax,-0x38(%rbp)
jmp    130d <USBHostEndpointConfig+0x20d>
mov    -0x30(%rbp),%rax
and    $0x8,%rax
cmp    $0x0,%rax
je     1308 <USBHostEndpointConfig+0x208>
mov    -0x38(%rbp),%rax
or     $0x10,%rax
mov    %rax,-0x38(%rbp)
jmp    130d <USBHostEndpointConfig+0x20d>
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    1409 <USBHostEndpointConfig+0x309>
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)
mov    -0x18(%rbp),%rax
mov    %ax,%cx
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdx
sub    $0x10,%rdx
add    %rdx,%rax
mov    %cx,0x114(%rax)
movq   $0x0,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x4,%rax
cmp    $0x0,%rax
je     13a8 <USBHostEndpointConfig+0x2a8>
mov    -0x38(%rbp),%rax
or     $0x80,%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
and    $0x10,%rax
cmp    $0x0,%rax
je     13cb <USBHostEndpointConfig+0x2cb>
mov    -0x38(%rbp),%rax
or     $0x28,%rax
mov    %rax,-0x38(%rbp)
jmp    13ee <USBHostEndpointConfig+0x2ee>
mov    -0x30(%rbp),%rax
and    $0x8,%rax
cmp    $0x0,%rax
je     13e9 <USBHostEndpointConfig+0x2e9>
mov    -0x38(%rbp),%rax
or     $0x20,%rax
mov    %rax,-0x38(%rbp)
jmp    13ee <USBHostEndpointConfig+0x2ee>
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    140e <USBHostEndpointConfig+0x30e>
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    11b9 <USBHostEndpointConfig+0xb9>
mov    %r10b,0x11c(%rdi)
mov    %cl,0x11d(%rdi)
mov    %dx,0x114(%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    %dx,0x110(%rdi)
test   $0x10,%r9b
jne    11ee <USBHostEndpointConfig+0xee>
rol    $0x4,%r9b
mov    %r9d,%eax
shr    $0x3,%al
shl    $0x3,%r9b
and    $0x80,%r9b
or     %al,%r9b
and    $0x90,%r9b
jmp    11f6 <USBHostEndpointConfig+0xf6>
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 %172
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 i16
%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 i16*
store volatile i16 %79, i16* %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 %171
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
%133 = load i64, i64* %9
%134 = trunc i64 %133 to i16
%135 = load i64, i64* %7
%136 = load i64, i64* %8
%137 = sub i64 %136, 16
%138 = add i64 %135, %137
%139 = add i64 %138, 276
%140 = inttoptr i64 %139 to i16*
store volatile i16 %134, i16* %140
store i64 0, i64* %13
%141 = load i64, i64* %12
%142 = and i64 %141, 4
%143 = icmp ne i64 %142, 0
br i1 %143, label %144, label %147
144: ; preds = %116
%145 = load i64, i64* %13
%146 = or i64 %145, 128
store i64 %146, i64* %13
br label %147
147: ; preds = %144, %116
%148 = load i64, i64* %12
%149 = and i64 %148, 16
%150 = icmp ne i64 %149, 0
br i1 %150, label %151, label %154
151: ; preds = %147
%152 = load i64, i64* %13
%153 = or i64 %152, 40
store i64 %153, i64* %13
br label %162
154: ; preds = %147
%155 = load i64, i64* %12
%156 = and i64 %155, 8
%157 = icmp ne i64 %156, 0
br i1 %157, label %158, label %161
158: ; preds = %154
%159 = load i64, i64* %13
%160 = or i64 %159, 32
store i64 %160, i64* %13
br label %161
161: ; preds = %158, %154
br label %162
162: ; preds = %161, %151
%163 = load i64, i64* %13
%164 = trunc i64 %163 to i8
%165 = load i64, i64* %7
%166 = load i64, i64* %8
%167 = sub i64 %166, 16
%168 = add i64 %165, %167
%169 = add i64 %168, 279
%170 = inttoptr i64 %169 to i8*
store volatile i8 %164, i8* %170
br label %171
171: ; preds = %162, %107
br label %172
172: ; preds = %171, %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 %80
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 i16
%44 = add i64 %36, 272
%45 = inttoptr i64 %44 to i16*
store volatile i16 %43, i16* %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 %80
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 = trunc i64 %2 to i16
%68 = add i64 %36, 276
%69 = inttoptr i64 %68 to i16*
store volatile i16 %67, i16* %69
%70 = shl i64 %5, 5
%71 = and i64 %70, 128
%72 = and i64 %5, 16
%73 = icmp eq i64 %72, 0
%74 = shl i64 %5, 2
%75 = and i64 %74, 32
%76 = select i1 %73, i64 %75, i64 40
%77 = or i64 %71, %76
%78 = trunc i64 %77 to i8
%79 = add i64 %36, 279
br label %80
80: ; preds = %57, %61, %8
%81 = phi i64 [ %60, %57 ], [ %79, %61 ], [ %15, %8 ]
%82 = phi i8 [ %59, %57 ], [ %78, %61 ], [ %14, %8 ]
%83 = inttoptr i64 %81 to i8*
store volatile i8 %82, i8* %83
ret void
}