unsigned short ReadPad(int pad_connected) {
  unsigned short bits;
  if (pad_connected & 0x1) {
    (*(volatile unsigned char *)(0x20100000 + 0x75)) = 0x60;
    bits = ((*(volatile unsigned char *)(0x20100000 + 0x75)) & 0x8) << 9;
    (*(volatile unsigned char *)(0x20100000 + 0x75)) = 0x40;
    bits |= ((*(volatile unsigned char *)(0x20100000 + 0x75)) & 0xf) << 8;
    (*(volatile unsigned char *)(0x20100000 + 0x75)) = 0x20;
    bits |= ((*(volatile unsigned char *)(0x20100000 + 0x75)) & 0xf) << 4;
    (*(volatile unsigned char *)(0x20100000 + 0x75)) = 0x00;
    bits |= ((*(volatile unsigned char *)(0x20100000 + 0x75)) & 0xf);
  } else {
    (*(volatile unsigned char *)(0x20100000 + 0x77)) = 0x60;
    bits = ((*(volatile unsigned char *)(0x20100000 + 0x77)) & 0x8) << 9;
    (*(volatile unsigned char *)(0x20100000 + 0x77)) = 0x40;
    bits |= ((*(volatile unsigned char *)(0x20100000 + 0x77)) & 0xf) << 8;
    (*(volatile unsigned char *)(0x20100000 + 0x77)) = 0x20;
    bits |= ((*(volatile unsigned char *)(0x20100000 + 0x77)) & 0xf) << 4;
    (*(volatile unsigned char *)(0x20100000 + 0x77)) = 0x00;
    bits |= ((*(volatile unsigned char *)(0x20100000 + 0x77)) & 0xf);
  }
  return bits ^ 0x1FFF;
}


x86 assembly (clang, -O0):
<ReadPad>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    -0x4(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     119a <ReadPad+0x9a>
mov    $0x20100075,%eax
movb   $0x60,(%rax)
mov    $0x20100075,%eax
mov    (%rax),%al
movzbl %al,%eax
and    $0x8,%eax
shl    $0x9,%eax
mov    %ax,-0x6(%rbp)
mov    $0x20100075,%eax
movb   $0x40,(%rax)
mov    $0x20100075,%eax
mov    (%rax),%al
movzbl %al,%ecx
and    $0xf,%ecx
shl    $0x8,%ecx
movzwl -0x6(%rbp),%eax
or     %ecx,%eax
mov    %ax,-0x6(%rbp)
mov    $0x20100075,%eax
movb   $0x20,(%rax)
mov    $0x20100075,%eax
mov    (%rax),%al
movzbl %al,%ecx
and    $0xf,%ecx
shl    $0x4,%ecx
movzwl -0x6(%rbp),%eax
or     %ecx,%eax
mov    %ax,-0x6(%rbp)
mov    $0x20100075,%eax
movb   $0x0,(%rax)
mov    $0x20100075,%eax
mov    (%rax),%al
movzbl %al,%ecx
and    $0xf,%ecx
movzwl -0x6(%rbp),%eax
or     %ecx,%eax
mov    %ax,-0x6(%rbp)
jmp    1219 <ReadPad+0x119>
mov    $0x20100077,%eax
movb   $0x60,(%rax)
mov    $0x20100077,%eax
mov    (%rax),%al
movzbl %al,%eax
and    $0x8,%eax
shl    $0x9,%eax
mov    %ax,-0x6(%rbp)
mov    $0x20100077,%eax
movb   $0x40,(%rax)
mov    $0x20100077,%eax
mov    (%rax),%al
movzbl %al,%ecx
and    $0xf,%ecx
shl    $0x8,%ecx
movzwl -0x6(%rbp),%eax
or     %ecx,%eax
mov    %ax,-0x6(%rbp)
mov    $0x20100077,%eax
movb   $0x20,(%rax)
mov    $0x20100077,%eax
mov    (%rax),%al
movzbl %al,%ecx
and    $0xf,%ecx
shl    $0x4,%ecx
movzwl -0x6(%rbp),%eax
or     %ecx,%eax
mov    %ax,-0x6(%rbp)
mov    $0x20100077,%eax
movb   $0x0,(%rax)
mov    $0x20100077,%eax
mov    (%rax),%al
movzbl %al,%ecx
and    $0xf,%ecx
movzwl -0x6(%rbp),%eax
or     %ecx,%eax
mov    %ax,-0x6(%rbp)
movzwl -0x6(%rbp),%eax
xor    $0x1fff,%eax
movzwl %ax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ReadPad>:
xor    %eax,%eax
test   $0x1,%dil
sete   %al
movb   $0x60,0x20100075(%rax,%rax,1)
60
movzbl 0x20100075(%rax,%rax,1),%ecx
20
and    $0x8,%ecx
shl    $0x9,%ecx
movb   $0x40,0x20100075(%rax,%rax,1)
40
movzbl 0x20100075(%rax,%rax,1),%edx
20
and    $0xf,%edx
shl    $0x8,%edx
or     %ecx,%edx
movb   $0x20,0x20100075(%rax,%rax,1)
20
mov    0x20100075(%rax,%rax,1),%cl
shl    $0x4,%cl
movzbl %cl,%ecx
or     %edx,%ecx
movb   $0x0,0x20100075(%rax,%rax,1)
movzbl 0x20100075(%rax,%rax,1),%eax
20
and    $0xf,%eax
or     %ecx,%eax
xor    $0x1fff,%eax
ret

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

LLVM IR (-O2):
define zeroext i16 @ReadPad(i32 %0) {
%2 = and i32 %0, 1
%3 = icmp eq i32 %2, 0
%4 = select i1 %3, i8* inttoptr (i64 537919607 to i8*), i8* inttoptr (i64 537919605 to i8*)
store volatile i8 96, i8* %4
%5 = load volatile i8, i8* %4
%6 = and i8 %5, 8
%7 = zext i8 %6 to i16
%8 = shl nuw nsw i16 %7, 9
store volatile i8 64, i8* %4
%9 = load volatile i8, i8* %4
%10 = and i8 %9, 15
%11 = zext i8 %10 to i16
%12 = shl nuw nsw i16 %11, 8
%13 = or i16 %12, %8
store volatile i8 32, i8* %4
%14 = load volatile i8, i8* %4
%15 = shl i8 %14, 4
%16 = zext i8 %15 to i16
%17 = or i16 %13, %16
store volatile i8 0, i8* %4
%18 = load volatile i8, i8* %4
%19 = and i8 %18, 15
%20 = zext i8 %19 to i16
%21 = or i16 %17, %20
%22 = xor i16 %21, 8191
ret i16 %22
}