#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 GPIOBaseValid(unsigned long);
void GPIOPadConfigGet(unsigned long ulPort, unsigned char ucPin,
                      unsigned long *pulStrength, unsigned long *pulPinType) {
  unsigned long ulPinType, ulStrength;
  DEBUG_ASSERT(GPIOBaseValid(ulPort));
  DEBUG_ASSERT(ucPin < 8);
  ucPin = (1 << ucPin);
  ulStrength =
      (((*((volatile unsigned long *)(ulPort + 0x00000500))) & ucPin) ? 1 : 0);
  ulStrength |=
      (((*((volatile unsigned long *)(ulPort + 0x00000504))) & ucPin) ? 2 : 0);
  ulStrength |=
      (((*((volatile unsigned long *)(ulPort + 0x00000508))) & ucPin) ? 4 : 0);
  ulStrength |=
      (((*((volatile unsigned long *)(ulPort + 0x00000518))) & ucPin) ? 8 : 0);
  *pulStrength = ulStrength;
  ulPinType =
      (((*((volatile unsigned long *)(ulPort + 0x0000050C))) & ucPin) ? 1 : 0);
  ulPinType |=
      (((*((volatile unsigned long *)(ulPort + 0x00000510))) & ucPin) ? 2 : 0);
  ulPinType |=
      (((*((volatile unsigned long *)(ulPort + 0x00000514))) & ucPin) ? 4 : 0);
  ulPinType |=
      (((*((volatile unsigned long *)(ulPort + 0x0000051C))) & ucPin) ? 8 : 0);
  *pulPinType = ulPinType;
}


x86 assembly (clang, -O0):
<GPIOPadConfigGet>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %sil,%al
mov    %rdi,-0x8(%rbp)
mov    %al,-0x9(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <GPIOBaseValid@plt>
mov    %eax,%edi
call   1040 <DEBUG_ASSERT@plt>
movzbl -0x9(%rbp),%eax
cmp    $0x8,%eax
setl   %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <DEBUG_ASSERT@plt>
movzbl -0x9(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
mov    %al,-0x9(%rbp)
mov    -0x8(%rbp),%rax
mov    0x500(%rax),%rdx
movzbl -0x9(%rbp),%eax
and    %rax,%rdx
xor    %eax,%eax
mov    $0x1,%ecx
cmp    $0x0,%rdx
cmovne %ecx,%eax
cltq
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    0x504(%rax),%rdx
movzbl -0x9(%rbp),%eax
and    %rax,%rdx
xor    %eax,%eax
mov    $0x2,%ecx
cmp    $0x0,%rdx
cmovne %ecx,%eax
cltq
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    0x508(%rax),%rdx
movzbl -0x9(%rbp),%eax
and    %rax,%rdx
xor    %eax,%eax
mov    $0x4,%ecx
cmp    $0x0,%rdx
cmovne %ecx,%eax
cltq
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    0x518(%rax),%rdx
movzbl -0x9(%rbp),%eax
and    %rax,%rdx
xor    %eax,%eax
mov    $0x8,%ecx
cmp    $0x0,%rdx
cmovne %ecx,%eax
cltq
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
mov    0x50c(%rax),%rdx
movzbl -0x9(%rbp),%eax
and    %rax,%rdx
xor    %eax,%eax
mov    $0x1,%ecx
cmp    $0x0,%rdx
cmovne %ecx,%eax
cltq
mov    %rax,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    0x510(%rax),%rdx
movzbl -0x9(%rbp),%eax
and    %rax,%rdx
xor    %eax,%eax
mov    $0x2,%ecx
cmp    $0x0,%rdx
cmovne %ecx,%eax
cltq
or     -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    0x514(%rax),%rdx
movzbl -0x9(%rbp),%eax
and    %rax,%rdx
xor    %eax,%eax
mov    $0x4,%ecx
cmp    $0x0,%rdx
cmovne %ecx,%eax
cltq
or     -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    0x51c(%rax),%rdx
movzbl -0x9(%rbp),%eax
and    %rax,%rdx
xor    %eax,%eax
mov    $0x8,%ecx
cmp    $0x0,%rdx
cmovne %ecx,%eax
cltq
or     -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<GPIOPadConfigGet>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %rcx,%r14
mov    %rdx,%r15
mov    %esi,%ebp
mov    %rdi,%rbx
call   1030 <GPIOBaseValid@plt>
mov    %eax,%edi
call   1040 <DEBUG_ASSERT@plt>
xor    %edi,%edi
cmp    $0x8,%bpl
setb   %dil
call   1040 <DEBUG_ASSERT@plt>
mov    $0x1,%eax
mov    %ebp,%ecx
shl    %cl,%eax
mov    0x500(%rbx),%rcx
movzbl %al,%eax
xor    %edx,%edx
test   %eax,%ecx
setne  %dl
mov    0x504(%rbx),%rcx
xor    %esi,%esi
test   %eax,%ecx
setne  %sil
lea    (%rdx,%rsi,2),%rcx
mov    0x508(%rbx),%rdx
xor    %esi,%esi
test   %eax,%edx
setne  %sil
lea    (%rcx,%rsi,4),%rcx
mov    0x518(%rbx),%rdx
xor    %esi,%esi
test   %eax,%edx
setne  %sil
lea    (%rcx,%rsi,8),%rcx
mov    %rcx,(%r15)
mov    0x50c(%rbx),%rcx
xor    %edx,%edx
test   %eax,%ecx
setne  %dl
mov    0x510(%rbx),%rcx
xor    %esi,%esi
test   %eax,%ecx
setne  %sil
lea    (%rdx,%rsi,2),%rcx
mov    0x514(%rbx),%rdx
xor    %esi,%esi
test   %eax,%edx
setne  %sil
lea    (%rcx,%rsi,4),%rcx
mov    0x51c(%rbx),%rdx
xor    %esi,%esi
test   %eax,%edx
setne  %sil
lea    (%rcx,%rsi,8),%rax
mov    %rax,(%r14)
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @GPIOPadConfigGet(i64 %0, i8 zeroext %1, i64* %2, i64* %3) {
%5 = alloca i64
%6 = alloca i8
%7 = alloca i64*
%8 = alloca i64*
%9 = alloca i64
%10 = alloca i64
store i64 %0, i64* %5
store i8 %1, i8* %6
store i64* %2, i64** %7
store i64* %3, i64** %8
%11 = load i64, i64* %5
%12 = call i32 @GPIOBaseValid(i64 %11)
%13 = call i32 @DEBUG_ASSERT(i32 %12)
%14 = load i8, i8* %6
%15 = zext i8 %14 to i32
%16 = icmp slt i32 %15, 8
%17 = zext i1 %16 to i32
%18 = call i32 @DEBUG_ASSERT(i32 %17)
%19 = load i8, i8* %6
%20 = zext i8 %19 to i32
%21 = shl i32 1, %20
%22 = trunc i32 %21 to i8
store i8 %22, i8* %6
%23 = load i64, i64* %5
%24 = add i64 %23, 1280
%25 = inttoptr i64 %24 to i64*
%26 = load volatile i64, i64* %25
%27 = load i8, i8* %6
%28 = zext i8 %27 to i64
%29 = and i64 %26, %28
%30 = icmp ne i64 %29, 0
%31 = zext i1 %30 to i64
%32 = select i1 %30, i32 1, i32 0
%33 = sext i32 %32 to i64
store i64 %33, i64* %10
%34 = load i64, i64* %5
%35 = add i64 %34, 1284
%36 = inttoptr i64 %35 to i64*
%37 = load volatile i64, i64* %36
%38 = load i8, i8* %6
%39 = zext i8 %38 to i64
%40 = and i64 %37, %39
%41 = icmp ne i64 %40, 0
%42 = zext i1 %41 to i64
%43 = select i1 %41, i32 2, i32 0
%44 = sext i32 %43 to i64
%45 = load i64, i64* %10
%46 = or i64 %45, %44
store i64 %46, i64* %10
%47 = load i64, i64* %5
%48 = add i64 %47, 1288
%49 = inttoptr i64 %48 to i64*
%50 = load volatile i64, i64* %49
%51 = load i8, i8* %6
%52 = zext i8 %51 to i64
%53 = and i64 %50, %52
%54 = icmp ne i64 %53, 0
%55 = zext i1 %54 to i64
%56 = select i1 %54, i32 4, i32 0
%57 = sext i32 %56 to i64
%58 = load i64, i64* %10
%59 = or i64 %58, %57
store i64 %59, i64* %10
%60 = load i64, i64* %5
%61 = add i64 %60, 1304
%62 = inttoptr i64 %61 to i64*
%63 = load volatile i64, i64* %62
%64 = load i8, i8* %6
%65 = zext i8 %64 to i64
%66 = and i64 %63, %65
%67 = icmp ne i64 %66, 0
%68 = zext i1 %67 to i64
%69 = select i1 %67, i32 8, i32 0
%70 = sext i32 %69 to i64
%71 = load i64, i64* %10
%72 = or i64 %71, %70
store i64 %72, i64* %10
%73 = load i64, i64* %10
%74 = load i64*, i64** %7
store i64 %73, i64* %74
%75 = load i64, i64* %5
%76 = add i64 %75, 1292
%77 = inttoptr i64 %76 to i64*
%78 = load volatile i64, i64* %77
%79 = load i8, i8* %6
%80 = zext i8 %79 to i64
%81 = and i64 %78, %80
%82 = icmp ne i64 %81, 0
%83 = zext i1 %82 to i64
%84 = select i1 %82, i32 1, i32 0
%85 = sext i32 %84 to i64
store i64 %85, i64* %9
%86 = load i64, i64* %5
%87 = add i64 %86, 1296
%88 = inttoptr i64 %87 to i64*
%89 = load volatile i64, i64* %88
%90 = load i8, i8* %6
%91 = zext i8 %90 to i64
%92 = and i64 %89, %91
%93 = icmp ne i64 %92, 0
%94 = zext i1 %93 to i64
%95 = select i1 %93, i32 2, i32 0
%96 = sext i32 %95 to i64
%97 = load i64, i64* %9
%98 = or i64 %97, %96
store i64 %98, i64* %9
%99 = load i64, i64* %5
%100 = add i64 %99, 1300
%101 = inttoptr i64 %100 to i64*
%102 = load volatile i64, i64* %101
%103 = load i8, i8* %6
%104 = zext i8 %103 to i64
%105 = and i64 %102, %104
%106 = icmp ne i64 %105, 0
%107 = zext i1 %106 to i64
%108 = select i1 %106, i32 4, i32 0
%109 = sext i32 %108 to i64
%110 = load i64, i64* %9
%111 = or i64 %110, %109
store i64 %111, i64* %9
%112 = load i64, i64* %5
%113 = add i64 %112, 1308
%114 = inttoptr i64 %113 to i64*
%115 = load volatile i64, i64* %114
%116 = load i8, i8* %6
%117 = zext i8 %116 to i64
%118 = and i64 %115, %117
%119 = icmp ne i64 %118, 0
%120 = zext i1 %119 to i64
%121 = select i1 %119, i32 8, i32 0
%122 = sext i32 %121 to i64
%123 = load i64, i64* %9
%124 = or i64 %123, %122
store i64 %124, i64* %9
%125 = load i64, i64* %9
%126 = load i64*, i64** %8
store i64 %125, i64* %126
ret void
}

LLVM IR (-O2):
define void @GPIOPadConfigGet(i64 %0, i8 zeroext %1, i64* nocapture writeonly %2, i64* nocapture writeonly %3) {
%5 = tail call i32 @GPIOBaseValid(i64 %0)
%6 = tail call i32 @DEBUG_ASSERT(i32 %5)
%7 = zext i8 %1 to i32
%8 = icmp ult i8 %1, 8
%9 = zext i1 %8 to i32
%10 = tail call i32 @DEBUG_ASSERT(i32 %9)
%11 = shl nuw i32 1, %7
%12 = add i64 %0, 1280
%13 = inttoptr i64 %12 to i64*
%14 = load volatile i64, i64* %13
%15 = and i32 %11, 255
%16 = zext i32 %15 to i64
%17 = and i64 %14, %16
%18 = icmp ne i64 %17, 0
%19 = zext i1 %18 to i64
%20 = add i64 %0, 1284
%21 = inttoptr i64 %20 to i64*
%22 = load volatile i64, i64* %21
%23 = and i64 %22, %16
%24 = icmp eq i64 %23, 0
%25 = select i1 %24, i64 0, i64 2
%26 = or i64 %25, %19
%27 = add i64 %0, 1288
%28 = inttoptr i64 %27 to i64*
%29 = load volatile i64, i64* %28
%30 = and i64 %29, %16
%31 = icmp eq i64 %30, 0
%32 = select i1 %31, i64 0, i64 4
%33 = or i64 %26, %32
%34 = add i64 %0, 1304
%35 = inttoptr i64 %34 to i64*
%36 = load volatile i64, i64* %35
%37 = and i64 %36, %16
%38 = icmp eq i64 %37, 0
%39 = select i1 %38, i64 0, i64 8
%40 = or i64 %33, %39
store i64 %40, i64* %2
%41 = add i64 %0, 1292
%42 = inttoptr i64 %41 to i64*
%43 = load volatile i64, i64* %42
%44 = and i64 %43, %16
%45 = icmp ne i64 %44, 0
%46 = zext i1 %45 to i64
%47 = add i64 %0, 1296
%48 = inttoptr i64 %47 to i64*
%49 = load volatile i64, i64* %48
%50 = and i64 %49, %16
%51 = icmp eq i64 %50, 0
%52 = select i1 %51, i64 0, i64 2
%53 = or i64 %52, %46
%54 = add i64 %0, 1300
%55 = inttoptr i64 %54 to i64*
%56 = load volatile i64, i64* %55
%57 = and i64 %56, %16
%58 = icmp eq i64 %57, 0
%59 = select i1 %58, i64 0, i64 4
%60 = or i64 %53, %59
%61 = add i64 %0, 1308
%62 = inttoptr i64 %61 to i64*
%63 = load volatile i64, i64* %62
%64 = and i64 %63, %16
%65 = icmp eq i64 %64, 0
%66 = select i1 %65, i64 0, i64 8
%67 = or i64 %60, %66
store i64 %67, i64* %3
ret void
}