#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 */
typedef size_t const uint64_t;
typedef int /*<<< orphan*/ h4;
typedef int /*<<< orphan*/ h3;
typedef int /*<<< orphan*/ h2;
typedef int /*<<< orphan*/ h1;
typedef int /*<<< orphan*/ h0;

/* Variables and functions */
size_t get_dram_mapping(void *phys_addr_p) {
  uint64_t phys_addr = (uint64_t)phys_addr_p;
  static const size_t h0[] = {14, 18};
  static const size_t h1[] = {15, 19};
  static const size_t h2[] = {16, 20};
  static const size_t h3[] = {17, 21};
  static const size_t h4[] = {7, 8, 9, 12, 13, 18, 19};
  size_t count = sizeof(h0) / sizeof(h0[0]);
  size_t hash = 0;
  for (size_t i = 0; i < count; i++) {
    hash ^= (phys_addr >> h0[i]) & 1;
  }
  count = sizeof(h1) / sizeof(h1[0]);
  size_t hash1 = 0;
  for (size_t i = 0; i < count; i++) {
    hash1 ^= (phys_addr >> h1[i]) & 1;
  }
  count = sizeof(h2) / sizeof(h2[0]);
  size_t hash2 = 0;
  for (size_t i = 0; i < count; i++) {
    hash2 ^= (phys_addr >> h2[i]) & 1;
  }
  count = sizeof(h3) / sizeof(h3[0]);
  size_t hash3 = 0;
  for (size_t i = 0; i < count; i++) {
    hash3 ^= (phys_addr >> h3[i]) & 1;
  }
  count = sizeof(h4) / sizeof(h4[0]);
  size_t hash4 = 0;
  for (size_t i = 0; i < count; i++) {
    hash4 ^= (phys_addr >> h4[i]) & 1;
  }
  return (hash4 << 4) | (hash3 << 3) | (hash2 << 2) | (hash1 << 1) | hash;
}


x86 assembly (clang, -O0):
<get_dram_mapping>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x10(%rbp)
movq   $0x2,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1169 <get_dram_mapping+0x69>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rdx
lea    0xebb(%rip),%rcx
mov    (%rcx,%rdx,8),%rcx
shr    %cl,%rax
and    $0x1,%rax
xor    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1128 <get_dram_mapping+0x28>
movq   $0x2,-0x18(%rbp)
movq   $0x0,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    11c2 <get_dram_mapping+0xc2>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rdx
lea    0xe72(%rip),%rcx
mov    (%rcx,%rdx,8),%rcx
shr    %cl,%rax
and    $0x1,%rax
xor    -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    1181 <get_dram_mapping+0x81>
movq   $0x2,-0x18(%rbp)
movq   $0x0,-0x40(%rbp)
movq   $0x0,-0x48(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    121b <get_dram_mapping+0x11b>
mov    -0x10(%rbp),%rax
mov    -0x48(%rbp),%rdx
lea    0xe29(%rip),%rcx
mov    (%rcx,%rdx,8),%rcx
shr    %cl,%rax
and    $0x1,%rax
xor    -0x40(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x48(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x48(%rbp)
jmp    11da <get_dram_mapping+0xda>
movq   $0x2,-0x18(%rbp)
movq   $0x0,-0x50(%rbp)
movq   $0x0,-0x58(%rbp)
mov    -0x58(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1274 <get_dram_mapping+0x174>
mov    -0x10(%rbp),%rax
mov    -0x58(%rbp),%rdx
lea    0xde0(%rip),%rcx
mov    (%rcx,%rdx,8),%rcx
shr    %cl,%rax
and    $0x1,%rax
xor    -0x50(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x58(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x58(%rbp)
jmp    1233 <get_dram_mapping+0x133>
movq   $0x7,-0x18(%rbp)
movq   $0x0,-0x60(%rbp)
movq   $0x0,-0x68(%rbp)
mov    -0x68(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    12cd <get_dram_mapping+0x1cd>
mov    -0x10(%rbp),%rax
mov    -0x68(%rbp),%rdx
lea    0xd97(%rip),%rcx
mov    (%rcx,%rdx,8),%rcx
shr    %cl,%rax
and    $0x1,%rax
xor    -0x60(%rbp),%rax
mov    %rax,-0x60(%rbp)
mov    -0x68(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x68(%rbp)
jmp    128c <get_dram_mapping+0x18c>
mov    -0x60(%rbp),%rax
shl    $0x4,%rax
mov    -0x50(%rbp),%rcx
shl    $0x3,%rcx
or     %rcx,%rax
mov    -0x40(%rbp),%rcx
shl    $0x2,%rcx
or     %rcx,%rax
mov    -0x30(%rbp),%rcx
shl    $0x1,%rcx
or     %rcx,%rax
or     -0x20(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<get_dram_mapping>:
mov    %edi,%r9d
shr    $0xe,%r9d
and    $0x1,%r9d
mov    %edi,%r10d
shr    $0x12,%r10d
and    $0x1,%r10d
mov    %edi,%edx
shr    $0xf,%edx
and    $0x1,%edx
mov    %edi,%r11d
shr    $0x13,%r11d
and    $0x1,%r11d
mov    %r11,%r8
xor    %r10,%r8
xor    %edx,%r11d
mov    %edi,%edx
shr    $0x10,%edx
mov    %edi,%esi
shr    $0x14,%esi
xor    %edx,%esi
mov    %rdi,%rdx
shr    $0x7,%rdx
mov    %rdi,%rax
shr    $0x8,%rax
xor    %eax,%edx
mov    %edi,%eax
shr    $0x9,%eax
mov    %edi,%ecx
shr    $0xc,%ecx
xor    %eax,%ecx
xor    %edx,%ecx
mov    %edi,%edx
shr    $0xd,%edx
xor    %ecx,%edx
and    $0x1,%edx
xor    %r8,%rdx
mov    %edi,%eax
shr    $0x11,%eax
shr    $0x15,%edi
xor    %eax,%edi
xor    %r9d,%r10d
shl    $0x4,%rdx
and    $0x1,%edi
and    $0x1,%esi
lea    (%r10,%r11,2),%rax
lea    (%rax,%rsi,4),%rax
lea    (%rax,%rdi,8),%rax
or     %rdx,%rax
ret

LLVM IR (-O0):
@get_dram_mapping.h0 = internal constant [2 x i64] [i64 14, i64 18]
@get_dram_mapping.h1 = internal constant [2 x i64] [i64 15, i64 19]
@get_dram_mapping.h2 = internal constant [2 x i64] [i64 16, i64 20]
@get_dram_mapping.h3 = internal constant [2 x i64] [i64 17, i64 21]
@get_dram_mapping.h4 = internal constant [7 x i64] [i64 7, i64 8, i64 9, i64 12, i64 13, i64 18, i64 19]
define i64 @get_dram_mapping(i8* %0) {
%2 = alloca i8*
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
%12 = alloca i64
%13 = alloca i64
%14 = alloca i64
store i8* %0, i8** %2
%15 = load i8*, i8** %2
%16 = ptrtoint i8* %15 to i64
store i64 %16, i64* %3
store i64 2, i64* %4
store i64 0, i64* %5
store i64 0, i64* %6
br label %17
17: ; preds = %30, %1
%18 = load i64, i64* %6
%19 = load i64, i64* %4
%20 = icmp ult i64 %18, %19
br i1 %20, label %21, label %33
21: ; preds = %17
%22 = load i64, i64* %3
%23 = load i64, i64* %6
%24 = getelementptr inbounds [2 x i64], [2 x i64]* @get_dram_mapping.h0, i64 0, i64 %23
%25 = load i64, i64* %24
%26 = lshr i64 %22, %25
%27 = and i64 %26, 1
%28 = load i64, i64* %5
%29 = xor i64 %28, %27
store i64 %29, i64* %5
br label %30
30: ; preds = %21
%31 = load i64, i64* %6
%32 = add i64 %31, 1
store i64 %32, i64* %6
br label %17
33: ; preds = %17
store i64 2, i64* %4
store i64 0, i64* %7
store i64 0, i64* %8
br label %34
34: ; preds = %47, %33
%35 = load i64, i64* %8
%36 = load i64, i64* %4
%37 = icmp ult i64 %35, %36
br i1 %37, label %38, label %50
38: ; preds = %34
%39 = load i64, i64* %3
%40 = load i64, i64* %8
%41 = getelementptr inbounds [2 x i64], [2 x i64]* @get_dram_mapping.h1, i64 0, i64 %40
%42 = load i64, i64* %41
%43 = lshr i64 %39, %42
%44 = and i64 %43, 1
%45 = load i64, i64* %7
%46 = xor i64 %45, %44
store i64 %46, i64* %7
br label %47
47: ; preds = %38
%48 = load i64, i64* %8
%49 = add i64 %48, 1
store i64 %49, i64* %8
br label %34
50: ; preds = %34
store i64 2, i64* %4
store i64 0, i64* %9
store i64 0, i64* %10
br label %51
51: ; preds = %64, %50
%52 = load i64, i64* %10
%53 = load i64, i64* %4
%54 = icmp ult i64 %52, %53
br i1 %54, label %55, label %67
55: ; preds = %51
%56 = load i64, i64* %3
%57 = load i64, i64* %10
%58 = getelementptr inbounds [2 x i64], [2 x i64]* @get_dram_mapping.h2, i64 0, i64 %57
%59 = load i64, i64* %58
%60 = lshr i64 %56, %59
%61 = and i64 %60, 1
%62 = load i64, i64* %9
%63 = xor i64 %62, %61
store i64 %63, i64* %9
br label %64
64: ; preds = %55
%65 = load i64, i64* %10
%66 = add i64 %65, 1
store i64 %66, i64* %10
br label %51
67: ; preds = %51
store i64 2, i64* %4
store i64 0, i64* %11
store i64 0, i64* %12
br label %68
68: ; preds = %81, %67
%69 = load i64, i64* %12
%70 = load i64, i64* %4
%71 = icmp ult i64 %69, %70
br i1 %71, label %72, label %84
72: ; preds = %68
%73 = load i64, i64* %3
%74 = load i64, i64* %12
%75 = getelementptr inbounds [2 x i64], [2 x i64]* @get_dram_mapping.h3, i64 0, i64 %74
%76 = load i64, i64* %75
%77 = lshr i64 %73, %76
%78 = and i64 %77, 1
%79 = load i64, i64* %11
%80 = xor i64 %79, %78
store i64 %80, i64* %11
br label %81
81: ; preds = %72
%82 = load i64, i64* %12
%83 = add i64 %82, 1
store i64 %83, i64* %12
br label %68
84: ; preds = %68
store i64 7, i64* %4
store i64 0, i64* %13
store i64 0, i64* %14
br label %85
85: ; preds = %98, %84
%86 = load i64, i64* %14
%87 = load i64, i64* %4
%88 = icmp ult i64 %86, %87
br i1 %88, label %89, label %101
89: ; preds = %85
%90 = load i64, i64* %3
%91 = load i64, i64* %14
%92 = getelementptr inbounds [7 x i64], [7 x i64]* @get_dram_mapping.h4, i64 0, i64 %91
%93 = load i64, i64* %92
%94 = lshr i64 %90, %93
%95 = and i64 %94, 1
%96 = load i64, i64* %13
%97 = xor i64 %96, %95
store i64 %97, i64* %13
br label %98
98: ; preds = %89
%99 = load i64, i64* %14
%100 = add i64 %99, 1
store i64 %100, i64* %14
br label %85
101: ; preds = %85
%102 = load i64, i64* %13
%103 = shl i64 %102, 4
%104 = load i64, i64* %11
%105 = shl i64 %104, 3
%106 = or i64 %103, %105
%107 = load i64, i64* %9
%108 = shl i64 %107, 2
%109 = or i64 %106, %108
%110 = load i64, i64* %7
%111 = shl i64 %110, 1
%112 = or i64 %109, %111
%113 = load i64, i64* %5
%114 = or i64 %112, %113
ret i64 %114
}

LLVM IR (-O2):
define i64 @get_dram_mapping(i8* %0) {
%2 = ptrtoint i8* %0 to i64
%3 = lshr i64 %2, 14
%4 = lshr i64 %2, 18
%5 = and i64 %4, 1
%6 = lshr i64 %2, 15
%7 = lshr i64 %2, 19
%8 = and i64 %7, 1
%9 = and i64 %3, 1
%10 = lshr i64 %2, 16
%11 = lshr i64 %2, 20
%12 = and i64 %6, 1
%13 = xor i64 %8, %12
%14 = lshr i64 %2, 17
%15 = lshr i64 %2, 21
%16 = xor i64 %11, %10
%17 = lshr i64 %2, 7
%18 = lshr i64 %2, 8
%19 = xor i64 %18, %17
%20 = lshr i64 %2, 9
%21 = xor i64 %20, %19
%22 = lshr i64 %2, 12
%23 = xor i64 %22, %21
%24 = lshr i64 %2, 13
%25 = xor i64 %24, %23
%26 = and i64 %25, 1
%27 = xor i64 %5, %26
%28 = xor i64 %8, %27
%29 = xor i64 %15, %14
%30 = xor i64 %5, %9
%31 = shl nuw nsw i64 %28, 4
%32 = shl nuw nsw i64 %29, 3
%33 = and i64 %32, 8
%34 = shl nuw nsw i64 %16, 2
%35 = and i64 %34, 4
%36 = shl nuw nsw i64 %13, 1
%37 = or i64 %36, %30
%38 = or i64 %37, %35
%39 = or i64 %38, %33
%40 = or i64 %39, %31
ret i64 %40
}