#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 */
struct rsdp_descriptor {
  int dummy;
};
typedef int /*<<< orphan*/ ptr;

/* Variables and functions */
scalar_t__ acpi_check_rsdp_header(unsigned int *);
int /*<<< orphan*/ map_page_pse(void *, void *, int);
int /*<<< orphan*/ unmap_page_pse(int /*<<< orphan*/);
struct rsdp_descriptor *acpi_get_rsd_ptr() {
  map_page_pse((void *)0, (void *)0, 2);
  unsigned int *ptr;
  for (ptr = (unsigned int *)0xE0000; (unsigned int)ptr < 0x100000;
       ptr += 0x10 / sizeof(ptr)) {
    if (acpi_check_rsdp_header(ptr)) {
      return (struct rsdp_descriptor *)ptr;
    }
  }
  int ebda = *((short *)0x40E);
  ebda = ebda * 0x10 & 0x000FFFFF;
  for (ptr = (unsigned int *)ebda; (int)ptr < ebda + 0x400;
       ptr += 0x10 / sizeof(ptr)) {
    if (acpi_check_rsdp_header(ptr)) {
      return (struct rsdp_descriptor *)ptr;
    }
  }
  unmap_page_pse(0);
  return 0;
}


x86 assembly (clang, -O0):
<acpi_get_rsd_ptr>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
xor    %eax,%eax
mov    %eax,%esi
mov    $0x2,%edx
mov    %rsi,%rdi
call   1050 <map_page_pse@plt>
mov    $0xe0000,%eax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
cmp    $0x100000,%eax
jae    1197 <acpi_get_rsd_ptr+0x67>
mov    -0x10(%rbp),%rdi
call   1040 <acpi_check_rsdp_header@plt>
cmp    $0x0,%rax
je     1181 <acpi_get_rsd_ptr+0x51>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1212 <acpi_get_rsd_ptr+0xe2>
jmp    1186 <acpi_get_rsd_ptr+0x56>
mov    -0x10(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x10(%rbp)
jmp    1152 <acpi_get_rsd_ptr+0x22>
mov    $0x40e,%eax
movswl (%rax),%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
shl    $0x4,%eax
and    $0xfffff,%eax
mov    %eax,-0x14(%rbp)
movslq -0x14(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x400,%ecx
cmp    %ecx,%eax
jge    1203 <acpi_get_rsd_ptr+0xd3>
mov    -0x10(%rbp),%rdi
call   1040 <acpi_check_rsdp_header@plt>
cmp    $0x0,%rax
je     11ed <acpi_get_rsd_ptr+0xbd>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1212 <acpi_get_rsd_ptr+0xe2>
jmp    11f2 <acpi_get_rsd_ptr+0xc2>
mov    -0x10(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x10(%rbp)
jmp    11b8 <acpi_get_rsd_ptr+0x88>
xor    %edi,%edi
call   1030 <unmap_page_pse@plt>
movq   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<acpi_get_rsd_ptr>:
push   %rbp
push   %r14
push   %rbx
xor    %edi,%edi
xor    %esi,%esi
mov    $0x2,%edx
call   1050 <map_page_pse@plt>
mov    $0xe0000,%ebx
mov    $0xe0008,%ebp
nopl   0x0(%rax)
mov    %rbx,%rdi
call   1040 <acpi_check_rsdp_header@plt>
test   %rax,%rax
jne    11b3 <acpi_get_rsd_ptr+0x83>
add    $0x8,%rbx
mov    %rbp,%rax
add    $0x8,%rax
test   $0xfff00000,%ebp
mov    %rax,%rbp
je     1150 <acpi_get_rsd_ptr+0x20>
movzwl 0x40e,%eax
movzwl %ax,%r14d
shl    $0x4,%r14d
lea    0x400(%r14),%ebp
mov    %r14,%rbx
nopl   (%rax)
mov    %rbx,%rdi
call   1040 <acpi_check_rsdp_header@plt>
test   %rax,%rax
jne    11b3 <acpi_get_rsd_ptr+0x83>
add    $0x8,%rbx
add    $0x8,%r14d
cmp    %r14d,%ebp
jg     1190 <acpi_get_rsd_ptr+0x60>
xor    %ebx,%ebx
xor    %edi,%edi
call   1030 <unmap_page_pse@plt>
mov    %rbx,%rax
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
%struct.rsdp_descriptor = type { i32 }
define %struct.rsdp_descriptor* @acpi_get_rsd_ptr() {
%1 = alloca %struct.rsdp_descriptor*
%2 = alloca i32*
%3 = alloca i32
%4 = call i32 @map_page_pse(i8* null, i8* null, i32 2)
store i32* inttoptr (i64 917504 to i32*), i32** %2
br label %5
5: ; preds = %17, %0
%6 = load i32*, i32** %2
%7 = ptrtoint i32* %6 to i32
%8 = icmp ult i32 %7, 1048576
br i1 %8, label %9, label %20
9: ; preds = %5
%10 = load i32*, i32** %2
%11 = call i64 @acpi_check_rsdp_header(i32* %10)
%12 = icmp ne i64 %11, 0
br i1 %12, label %13, label %16
13: ; preds = %9
%14 = load i32*, i32** %2
%15 = bitcast i32* %14 to %struct.rsdp_descriptor*
store %struct.rsdp_descriptor* %15, %struct.rsdp_descriptor** %1
br label %48
16: ; preds = %9
br label %17
17: ; preds = %16
%18 = load i32*, i32** %2
%19 = getelementptr inbounds i32, i32* %18, i64 2
store i32* %19, i32** %2
br label %5
20: ; preds = %5
%21 = load i16, i16* inttoptr (i64 1038 to i16*)
%22 = sext i16 %21 to i32
store i32 %22, i32* %3
%23 = load i32, i32* %3
%24 = mul nsw i32 %23, 16
%25 = and i32 %24, 1048575
store i32 %25, i32* %3
%26 = load i32, i32* %3
%27 = sext i32 %26 to i64
%28 = inttoptr i64 %27 to i32*
store i32* %28, i32** %2
br label %29
29: ; preds = %43, %20
%30 = load i32*, i32** %2
%31 = ptrtoint i32* %30 to i32
%32 = load i32, i32* %3
%33 = add nsw i32 %32, 1024
%34 = icmp slt i32 %31, %33
br i1 %34, label %35, label %46
35: ; preds = %29
%36 = load i32*, i32** %2
%37 = call i64 @acpi_check_rsdp_header(i32* %36)
%38 = icmp ne i64 %37, 0
br i1 %38, label %39, label %42
39: ; preds = %35
%40 = load i32*, i32** %2
%41 = bitcast i32* %40 to %struct.rsdp_descriptor*
store %struct.rsdp_descriptor* %41, %struct.rsdp_descriptor** %1
br label %48
42: ; preds = %35
br label %43
43: ; preds = %42
%44 = load i32*, i32** %2
%45 = getelementptr inbounds i32, i32* %44, i64 2
store i32* %45, i32** %2
br label %29
46: ; preds = %29
%47 = call i32 @unmap_page_pse(i32 0)
store %struct.rsdp_descriptor* null, %struct.rsdp_descriptor** %1
br label %48
48: ; preds = %46, %39, %13
%49 = load %struct.rsdp_descriptor*, %struct.rsdp_descriptor** %1
ret %struct.rsdp_descriptor* %49
}

LLVM IR (-O2):
%struct.rsdp_descriptor = type { i32 }
define %struct.rsdp_descriptor* @acpi_get_rsd_ptr() {
%1 = tail call i32 @map_page_pse(i8* null, i8* null, i32 2)
br label %2
2: ; preds = %0, %8
%3 = phi i32* [ inttoptr (i64 917504 to i32*), %0 ], [ %9, %8 ]
%4 = tail call i64 @acpi_check_rsdp_header(i32* %3)
%5 = icmp eq i64 %4, 0
br i1 %5, label %8, label %6
6: ; preds = %2
%7 = bitcast i32* %3 to %struct.rsdp_descriptor*
br label %34
8: ; preds = %2
%9 = getelementptr inbounds i32, i32* %3, i64 2
%10 = ptrtoint i32* %9 to i64
%11 = and i64 %10, 4293918720
%12 = icmp eq i64 %11, 0
br i1 %12, label %2, label %13
13: ; preds = %8
%14 = load i16, i16* inttoptr (i64 1038 to i16*)
%15 = sext i16 %14 to i32
%16 = shl nsw i32 %15, 4
%17 = and i32 %16, 1048560
%18 = zext i32 %17 to i64
%19 = inttoptr i64 %18 to i32*
%20 = add nuw nsw i32 %17, 1024
br label %21
21: ; preds = %13, %27
%22 = phi i32* [ %19, %13 ], [ %28, %27 ]
%23 = tail call i64 @acpi_check_rsdp_header(i32* %22)
%24 = icmp eq i64 %23, 0
br i1 %24, label %27, label %25
25: ; preds = %21
%26 = bitcast i32* %22 to %struct.rsdp_descriptor*
br label %34
27: ; preds = %21
%28 = getelementptr inbounds i32, i32* %22, i64 2
%29 = ptrtoint i32* %28 to i64
%30 = trunc i64 %29 to i32
%31 = icmp sgt i32 %20, %30
br i1 %31, label %21, label %32
32: ; preds = %27
%33 = tail call i32 @unmap_page_pse(i32 0)
br label %34
34: ; preds = %25, %32, %6
%35 = phi %struct.rsdp_descriptor* [ %7, %6 ], [ %26, %25 ], [ null, %32 ]
ret %struct.rsdp_descriptor* %35
}