unsigned long PRCMDeviceTypeGet() {
  unsigned long ulDevType;
  unsigned long ulChipId;
  unsigned long ulDevMajorVer;
  unsigned long ulDevMinorVer;
  ulChipId = (*((volatile unsigned long *)(0x4402D000 + 0x00000C80)));
  ulDevMajorVer = ((ulChipId >> 28) & 0xF);
  ulDevMinorVer = ((ulChipId >> 24) & 0xF);
  ulChipId =
      (((*((volatile unsigned long *)(0x4402D000 + 0x00000C80))) >> 16) & 0x1F);
  switch ((ulChipId & 0xF)) {
  case 0x0:
    ulDevType = 0x00000001;
    break;
  case 0x1:
    ulDevType = 0x00000002 | 0x00000010;
    break;
  case 0x3:
    ulDevType = 0x00000004 | 0x00000010;
    break;
  case 0x8:
    ulDevType = 0x00000001 | 0x00000008;
    break;
  case 0x9:
    ulDevType = 0x00000002 | 0x00000008;
    break;
  case 0xB:
    ulDevType = 0x00000004 | 0x00000008 | 0x00000010;
    break;
  default:
    ulDevType = 0x0;
  }
  if (ulDevType != 0) {
    if (ulDevMajorVer == 0x3) {
      ulDevType |= 0x00000040;
    } else if (ulDevMajorVer == 0x2) {
      ulDevType |= (0x00000010 | 0x00000040);
      if (((ulDevType & 0x00000004) != 0)) {
        if ((ulDevMinorVer == 0x0)) {
          ulDevType |= 0x00010000;
        } else {
          ulDevType |= 0x00020000;
        }
      } else {
        if ((ulDevMinorVer == 0x1)) {
          ulDevType |= 0x00010000;
        }
      }
    } else {
      if ((ulDevMinorVer == 0x4)) {
        if (((ulDevType & 0x00000004) != 0)) {
          ulDevType |= (0x00000010 | 0x00000040);
        } else {
          ulDevType |= 0x00000020;
        }
      } else {
        ulDevType |= (0x00000010 | 0x00000020);
      }
    }
  }
  return ulDevType;
}


x86 assembly (clang, -O0):
<PRCMDeviceTypeGet>:
push   %rbp
mov    %rsp,%rbp
mov    0x4402dc80,%rax
44
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
shr    $0x1c,%eax
mov    %rax,-0x18(%rbp)
movzbl -0xd(%rbp),%eax
and    $0xf,%eax
mov    %rax,-0x20(%rbp)
mov    0x4402dc80,%rax
44
shr    $0x10,%eax
and    $0x1f,%eax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
and    $0xf,%eax
mov    %rax,-0x28(%rbp)
sub    $0xb,%rax
ja     11ae <PRCMDeviceTypeGet+0xae>
mov    -0x28(%rbp),%rax
lea    0xea9(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movq   $0x1,-0x8(%rbp)
jmp    11b6 <PRCMDeviceTypeGet+0xb6>
movq   $0x12,-0x8(%rbp)
jmp    11b6 <PRCMDeviceTypeGet+0xb6>
movq   $0x14,-0x8(%rbp)
jmp    11b6 <PRCMDeviceTypeGet+0xb6>
movq   $0x9,-0x8(%rbp)
jmp    11b6 <PRCMDeviceTypeGet+0xb6>
movq   $0xa,-0x8(%rbp)
jmp    11b6 <PRCMDeviceTypeGet+0xb6>
movq   $0x1c,-0x8(%rbp)
jmp    11b6 <PRCMDeviceTypeGet+0xb6>
movq   $0x0,-0x8(%rbp)
cmpq   $0x0,-0x8(%rbp)
je     12b4 <PRCMDeviceTypeGet+0x1b4>
cmpq   $0x3,-0x18(%rbp)
jne    11dd <PRCMDeviceTypeGet+0xdd>
mov    -0x8(%rbp),%rax
or     $0x40,%rax
mov    %rax,-0x8(%rbp)
jmp    12af <PRCMDeviceTypeGet+0x1af>
cmpq   $0x2,-0x18(%rbp)
jne    125a <PRCMDeviceTypeGet+0x15a>
mov    -0x8(%rbp),%rax
or     $0x50,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
and    $0x4,%rax
cmp    $0x0,%rax
je     1237 <PRCMDeviceTypeGet+0x137>
cmpq   $0x0,-0x20(%rbp)
jne    1224 <PRCMDeviceTypeGet+0x124>
mov    -0x8(%rbp),%rax
or     $0x10000,%rax
mov    %rax,-0x8(%rbp)
jmp    1232 <PRCMDeviceTypeGet+0x132>
mov    -0x8(%rbp),%rax
or     $0x20000,%rax
mov    %rax,-0x8(%rbp)
jmp    1255 <PRCMDeviceTypeGet+0x155>
cmpq   $0x1,-0x20(%rbp)
jne    1250 <PRCMDeviceTypeGet+0x150>
mov    -0x8(%rbp),%rax
or     $0x10000,%rax
mov    %rax,-0x8(%rbp)
jmp    1255 <PRCMDeviceTypeGet+0x155>
jmp    12aa <PRCMDeviceTypeGet+0x1aa>
cmpq   $0x4,-0x20(%rbp)
jne    1299 <PRCMDeviceTypeGet+0x199>
mov    -0x8(%rbp),%rax
and    $0x4,%rax
cmp    $0x0,%rax
je     1288 <PRCMDeviceTypeGet+0x188>
mov    -0x8(%rbp),%rax
or     $0x50,%rax
mov    %rax,-0x8(%rbp)
jmp    1294 <PRCMDeviceTypeGet+0x194>
mov    -0x8(%rbp),%rax
or     $0x20,%rax
mov    %rax,-0x8(%rbp)
jmp    12a5 <PRCMDeviceTypeGet+0x1a5>
mov    -0x8(%rbp),%rax
or     $0x30,%rax
mov    %rax,-0x8(%rbp)
jmp    12aa <PRCMDeviceTypeGet+0x1aa>
jmp    12af <PRCMDeviceTypeGet+0x1af>
jmp    12b4 <PRCMDeviceTypeGet+0x1b4>
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<PRCMDeviceTypeGet>:
mov    0x4402dc80,%rcx
44
mov    0x4402dc80,%rdx
44
mov    %edx,%eax
shr    $0x10,%eax
and    $0xf,%eax
cmp    $0xb,%eax
ja     1127 <PRCMDeviceTypeGet+0x27>
mov    $0xb0b,%esi
bt     %eax,%esi
jb     112a <PRCMDeviceTypeGet+0x2a>
xor    %eax,%eax
ret
mov    %ecx,%esi
shr    $0x1c,%esi
shr    $0x18,%ecx
and    $0xf,%ecx
lea    0xec4(%rip),%rdi
mov    (%rdi,%rax,8),%rax
cmp    $0x2,%esi
je     114f <PRCMDeviceTypeGet+0x4f>
cmp    $0x3,%esi
jne    1169 <PRCMDeviceTypeGet+0x69>
or     $0x40,%rax
ret
and    $0x70000,%edx
cmp    $0x30000,%edx
jne    1181 <PRCMDeviceTypeGet+0x81>
test   %rcx,%rcx
je     11a2 <PRCMDeviceTypeGet+0xa2>
or     $0x20050,%rax
ret
cmp    $0x4,%ecx
jne    1198 <PRCMDeviceTypeGet+0x98>
and    $0x70000,%edx
cmp    $0x30000,%edx
jne    119d <PRCMDeviceTypeGet+0x9d>
or     $0x50,%rax
ret
xor    %edx,%edx
cmp    $0x1,%ecx
sete   %dl
shl    $0x10,%rdx
or     %rax,%rdx
or     $0x50,%rdx
mov    %rdx,%rax
ret
or     $0x30,%rax
ret
or     $0x20,%rax
ret
or     $0x10050,%rax
ret

LLVM IR (-O0):
define i64 @PRCMDeviceTypeGet() {
%1 = alloca i64
%2 = alloca i64
%3 = alloca i64
%4 = alloca i64
%5 = load volatile i64, i64* inttoptr (i64 1141038208 to i64*)
store i64 %5, i64* %2
%6 = load i64, i64* %2
%7 = lshr i64 %6, 28
%8 = and i64 %7, 15
store i64 %8, i64* %3
%9 = load i64, i64* %2
%10 = lshr i64 %9, 24
%11 = and i64 %10, 15
store i64 %11, i64* %4
%12 = load volatile i64, i64* inttoptr (i64 1141038208 to i64*)
%13 = lshr i64 %12, 16
%14 = and i64 %13, 31
store i64 %14, i64* %2
%15 = load i64, i64* %2
%16 = and i64 %15, 15
switch i64 %16, label %23 [
i64 0, label %17
i64 1, label %18
i64 3, label %19
i64 8, label %20
i64 9, label %21
i64 11, label %22
]
17: ; preds = %0
store i64 1, i64* %1
br label %24
18: ; preds = %0
store i64 18, i64* %1
br label %24
19: ; preds = %0
store i64 20, i64* %1
br label %24
20: ; preds = %0
store i64 9, i64* %1
br label %24
21: ; preds = %0
store i64 10, i64* %1
br label %24
22: ; preds = %0
store i64 28, i64* %1
br label %24
23: ; preds = %0
store i64 0, i64* %1
br label %24
24: ; preds = %23, %22, %21, %20, %19, %18, %17
%25 = load i64, i64* %1
%26 = icmp ne i64 %25, 0
br i1 %26, label %27, label %80
27: ; preds = %24
%28 = load i64, i64* %3
%29 = icmp eq i64 %28, 3
br i1 %29, label %30, label %33
30: ; preds = %27
%31 = load i64, i64* %1
%32 = or i64 %31, 64
store i64 %32, i64* %1
br label %79
33: ; preds = %27
%34 = load i64, i64* %3
%35 = icmp eq i64 %34, 2
br i1 %35, label %36, label %60
36: ; preds = %33
%37 = load i64, i64* %1
%38 = or i64 %37, 80
store i64 %38, i64* %1
%39 = load i64, i64* %1
%40 = and i64 %39, 4
%41 = icmp ne i64 %40, 0
br i1 %41, label %42, label %52
42: ; preds = %36
%43 = load i64, i64* %4
%44 = icmp eq i64 %43, 0
br i1 %44, label %45, label %48
45: ; preds = %42
%46 = load i64, i64* %1
%47 = or i64 %46, 65536
store i64 %47, i64* %1
br label %51
48: ; preds = %42
%49 = load i64, i64* %1
%50 = or i64 %49, 131072
store i64 %50, i64* %1
br label %51
51: ; preds = %48, %45
br label %59
52: ; preds = %36
%53 = load i64, i64* %4
%54 = icmp eq i64 %53, 1
br i1 %54, label %55, label %58
55: ; preds = %52
%56 = load i64, i64* %1
%57 = or i64 %56, 65536
store i64 %57, i64* %1
br label %58
58: ; preds = %55, %52
br label %59
59: ; preds = %58, %51
br label %78
60: ; preds = %33
%61 = load i64, i64* %4
%62 = icmp eq i64 %61, 4
br i1 %62, label %63, label %74
63: ; preds = %60
%64 = load i64, i64* %1
%65 = and i64 %64, 4
%66 = icmp ne i64 %65, 0
br i1 %66, label %67, label %70
67: ; preds = %63
%68 = load i64, i64* %1
%69 = or i64 %68, 80
store i64 %69, i64* %1
br label %73
70: ; preds = %63
%71 = load i64, i64* %1
%72 = or i64 %71, 32
store i64 %72, i64* %1
br label %73
73: ; preds = %70, %67
br label %77
74: ; preds = %60
%75 = load i64, i64* %1
%76 = or i64 %75, 48
store i64 %76, i64* %1
br label %77
77: ; preds = %74, %73
br label %78
78: ; preds = %77, %59
br label %79
79: ; preds = %78, %30
br label %80
80: ; preds = %79, %24
%81 = load i64, i64* %1
ret i64 %81
}

LLVM IR (-O2):
@switch.table.PRCMDeviceTypeGet = [12 x i64] [i64 1, i64 18, i64 1, i64 20, i64 1, i64 1, i64 1, i64 1, i64 9, i64 10, i64 1, i64 28]
define i64 @PRCMDeviceTypeGet() {
%1 = load volatile i64, i64* inttoptr (i64 1141038208 to i64*)
%2 = lshr i64 %1, 28
%3 = and i64 %2, 15
%4 = lshr i64 %1, 24
%5 = and i64 %4, 15
%6 = load volatile i64, i64* inttoptr (i64 1141038208 to i64*)
%7 = lshr i64 %6, 16
%8 = and i64 %7, 15
%9 = icmp ult i64 %8, 12
br i1 %9, label %10, label %44
10: ; preds = %0
%11 = trunc i64 %8 to i16
%12 = lshr i16 2827, %11
%13 = and i16 %12, 1
%14 = icmp eq i16 %13, 0
br i1 %14, label %44, label %15
15: ; preds = %10
%16 = getelementptr inbounds [12 x i64], [12 x i64]* @switch.table.PRCMDeviceTypeGet, i64 0, i64 %8
%17 = load i64, i64* %16
switch i64 %3, label %33 [
i64 3, label %18
i64 2, label %20
]
18: ; preds = %15
%19 = or i64 %17, 64
br label %44
20: ; preds = %15
%21 = and i64 %6, 458752
%22 = icmp eq i64 %21, 196608
br i1 %22, label %23, label %29
23: ; preds = %20
%24 = icmp eq i64 %5, 0
br i1 %24, label %25, label %27
25: ; preds = %23
%26 = or i64 %17, 65616
br label %44
27: ; preds = %23
%28 = or i64 %17, 131152
br label %44
29: ; preds = %20
%30 = icmp eq i64 %5, 1
%31 = select i1 %30, i64 65616, i64 80
%32 = or i64 %17, %31
br label %44
33: ; preds = %15
%34 = icmp eq i64 %5, 4
br i1 %34, label %35, label %42
35: ; preds = %33
%36 = and i64 %6, 458752
%37 = icmp eq i64 %36, 196608
br i1 %37, label %38, label %40
38: ; preds = %35
%39 = or i64 %17, 80
br label %44
40: ; preds = %35
%41 = or i64 %17, 32
br label %44
42: ; preds = %33
%43 = or i64 %17, 48
br label %44
44: ; preds = %10, %0, %29, %18, %42, %40, %38, %27, %25
%45 = phi i64 [ %19, %18 ], [ %26, %25 ], [ %28, %27 ], [ %39, %38 ], [ %41, %40 ], [ %43, %42 ], [ %32, %29 ], [ 0, %0 ], [ 0, %10 ]
ret i64 %45
}