void USBDevEndpointStallClear(unsigned long ulBase, unsigned long ulEndpoint,
                              unsigned long ulFlags) {
  ;

  ;

  if (ulEndpoint == 0x00000000) {
    (*((volatile unsigned char *)(ulBase + 0x00000102))) &= ~0x00000004;
  } else if (ulFlags == 0x00002000) {
    (*((volatile unsigned char *)(ulBase + 0x00000112 +
                                  (ulEndpoint - 0x10)))) &=
        ~(0x00000010 | 0x00000020);
    (*((volatile unsigned char *)(ulBase + 0x00000112 +
                                  (ulEndpoint - 0x10)))) |= 0x00000040;
  } else {
    (*((volatile unsigned char *)(ulBase + 0x00000116 +
                                  (ulEndpoint - 0x10)))) &=
        ~(0x00000020 | 0x00000040);
    (*((volatile unsigned char *)(ulBase + 0x00000116 +
                                  (ulEndpoint - 0x10)))) |= 0x00000040;
  }
}


x86 assembly (clang, -O0):
<USBDevEndpointStallClear>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1136 <USBDevEndpointStallClear+0x36>
mov    -0x8(%rbp),%rax
mov    0x102(%rax),%cl
movzbl %cl,%ecx
and    $0xfffffffb,%ecx
mov    %cl,0x102(%rax)
jmp    11ca <USBDevEndpointStallClear+0xca>
cmpq   $0x2000,-0x18(%rbp)
jne    1187 <USBDevEndpointStallClear+0x87>
mov    -0x8(%rbp),%rax
add    $0x112,%rax
mov    -0x10(%rbp),%rcx
sub    $0x10,%rcx
add    %rcx,%rax
mov    (%rax),%cl
movzbl %cl,%ecx
and    $0xffffffcf,%ecx
mov    %cl,(%rax)
mov    -0x8(%rbp),%rax
add    $0x112,%rax
mov    -0x10(%rbp),%rcx
sub    $0x10,%rcx
add    %rcx,%rax
mov    (%rax),%cl
movzbl %cl,%ecx
or     $0x40,%ecx
mov    %cl,(%rax)
jmp    11c5 <USBDevEndpointStallClear+0xc5>
mov    -0x8(%rbp),%rax
add    $0x116,%rax
mov    -0x10(%rbp),%rcx
sub    $0x10,%rcx
add    %rcx,%rax
mov    (%rax),%cl
movzbl %cl,%ecx
and    $0xffffff9f,%ecx
mov    %cl,(%rax)
mov    -0x8(%rbp),%rax
add    $0x116,%rax
mov    -0x10(%rbp),%rcx
sub    $0x10,%rcx
add    %rcx,%rax
mov    (%rax),%cl
movzbl %cl,%ecx
or     $0x40,%ecx
mov    %cl,(%rax)
jmp    11ca <USBDevEndpointStallClear+0xca>
pop    %rbp
ret

x86 assembly (clang, -O2):
<USBDevEndpointStallClear>:
test   %rsi,%rsi
je     111f <USBDevEndpointStallClear+0x1f>
cmp    $0x2000,%rdx
jne    1127 <USBDevEndpointStallClear+0x27>
andb   $0xcf,0x102(%rdi,%rsi,1)
cf
orb    $0x40,0x102(%rdi,%rsi,1)
40
ret
andb   $0xfb,0x102(%rdi)
ret
andb   $0x9f,0x106(%rsi,%rdi,1)
9f
orb    $0x40,0x106(%rsi,%rdi,1)
40
ret

LLVM IR (-O0):
define void @USBDevEndpointStallClear(i64 %0, i64 %1, i64 %2) {
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
store i64 %0, i64* %4
store i64 %1, i64* %5
store i64 %2, i64* %6
%7 = load i64, i64* %5
%8 = icmp eq i64 %7, 0
br i1 %8, label %9, label %17
9: ; preds = %3
%10 = load i64, i64* %4
%11 = add i64 %10, 258
%12 = inttoptr i64 %11 to i8*
%13 = load volatile i8, i8* %12
%14 = zext i8 %13 to i32
%15 = and i32 %14, -5
%16 = trunc i32 %15 to i8
store volatile i8 %16, i8* %12
br label %63
17: ; preds = %3
%18 = load i64, i64* %6
%19 = icmp eq i64 %18, 8192
br i1 %19, label %20, label %41
20: ; preds = %17
%21 = load i64, i64* %4
%22 = add i64 %21, 274
%23 = load i64, i64* %5
%24 = sub i64 %23, 16
%25 = add i64 %22, %24
%26 = inttoptr i64 %25 to i8*
%27 = load volatile i8, i8* %26
%28 = zext i8 %27 to i32
%29 = and i32 %28, -49
%30 = trunc i32 %29 to i8
store volatile i8 %30, i8* %26
%31 = load i64, i64* %4
%32 = add i64 %31, 274
%33 = load i64, i64* %5
%34 = sub i64 %33, 16
%35 = add i64 %32, %34
%36 = inttoptr i64 %35 to i8*
%37 = load volatile i8, i8* %36
%38 = zext i8 %37 to i32
%39 = or i32 %38, 64
%40 = trunc i32 %39 to i8
store volatile i8 %40, i8* %36
br label %62
41: ; preds = %17
%42 = load i64, i64* %4
%43 = add i64 %42, 278
%44 = load i64, i64* %5
%45 = sub i64 %44, 16
%46 = add i64 %43, %45
%47 = inttoptr i64 %46 to i8*
%48 = load volatile i8, i8* %47
%49 = zext i8 %48 to i32
%50 = and i32 %49, -97
%51 = trunc i32 %50 to i8
store volatile i8 %51, i8* %47
%52 = load i64, i64* %4
%53 = add i64 %52, 278
%54 = load i64, i64* %5
%55 = sub i64 %54, 16
%56 = add i64 %53, %55
%57 = inttoptr i64 %56 to i8*
%58 = load volatile i8, i8* %57
%59 = zext i8 %58 to i32
%60 = or i32 %59, 64
%61 = trunc i32 %60 to i8
store volatile i8 %61, i8* %57
br label %62
62: ; preds = %41, %20
br label %63
63: ; preds = %62, %9
ret void
}

LLVM IR (-O2):
define void @USBDevEndpointStallClear(i64 %0, i64 %1, i64 %2) {
%4 = icmp eq i64 %1, 0
br i1 %4, label %5, label %10
5: ; preds = %3
%6 = add i64 %0, 258
%7 = inttoptr i64 %6 to i8*
%8 = load volatile i8, i8* %7
%9 = and i8 %8, -5
store volatile i8 %9, i8* %7
br label %28
10: ; preds = %3
%11 = icmp eq i64 %2, 8192
br i1 %11, label %12, label %20
12: ; preds = %10
%13 = add i64 %0, 258
%14 = add i64 %13, %1
%15 = inttoptr i64 %14 to i8*
%16 = load volatile i8, i8* %15
%17 = and i8 %16, -49
store volatile i8 %17, i8* %15
%18 = load volatile i8, i8* %15
%19 = or i8 %18, 64
store volatile i8 %19, i8* %15
br label %28
20: ; preds = %10
%21 = add i64 %1, %0
%22 = add i64 %21, 262
%23 = inttoptr i64 %22 to i8*
%24 = load volatile i8, i8* %23
%25 = and i8 %24, -97
store volatile i8 %25, i8* %23
%26 = load volatile i8, i8* %23
%27 = or i8 %26, 64
store volatile i8 %27, i8* %23
br label %28
28: ; preds = %12, %20, %5
ret void
}