#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 */
unsigned char gfx_inb(int);
int /*<<< orphan*/ gfx_outb(int, unsigned char);
unsigned char gfx_gxm_config_read(unsigned char index) {
  unsigned char value = 0xFF;
  unsigned char lock;
  gfx_outb(0x22, 0xC3);
  lock = gfx_inb(0x23);
  gfx_outb(0x22, 0xC3);
  gfx_outb(0x23, (unsigned char)(lock | 0x10));
  gfx_outb(0x22, index);
  value = gfx_inb(0x23);
  gfx_outb(0x22, 0xC3);
  gfx_outb(0x23, lock);
  return (value);
}


x86 assembly (clang, -O0):
<gfx_gxm_config_read>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %dil,%al
mov    %al,-0x1(%rbp)
movb   $0xff,-0x2(%rbp)
mov    $0x22,%edi
mov    $0xc3,%esi
call   1040 <gfx_outb@plt>
mov    $0x23,%edi
call   1030 <gfx_inb@plt>
mov    %al,-0x3(%rbp)
mov    $0x22,%edi
mov    $0xc3,%esi
call   1040 <gfx_outb@plt>
movzbl -0x3(%rbp),%eax
or     $0x10,%eax
mov    $0x23,%edi
movzbl %al,%esi
call   1040 <gfx_outb@plt>
mov    $0x22,%edi
movzbl -0x1(%rbp),%esi
call   1040 <gfx_outb@plt>
mov    $0x23,%edi
call   1030 <gfx_inb@plt>
mov    %al,-0x2(%rbp)
mov    $0x22,%edi
mov    $0xc3,%esi
call   1040 <gfx_outb@plt>
mov    $0x23,%edi
movzbl -0x3(%rbp),%esi
call   1040 <gfx_outb@plt>
movzbl -0x2(%rbp),%eax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gfx_gxm_config_read>:
push   %rbp
push   %rbx
push   %rax
mov    %edi,%ebp
mov    $0x22,%edi
mov    $0xc3,%esi
call   1040 <gfx_outb@plt>
mov    $0x23,%edi
call   1030 <gfx_inb@plt>
mov    %eax,%ebx
mov    $0x22,%edi
mov    $0xc3,%esi
call   1040 <gfx_outb@plt>
mov    %ebx,%eax
or     $0x10,%al
movzbl %al,%esi
mov    $0x23,%edi
call   1040 <gfx_outb@plt>
mov    $0x22,%edi
mov    %ebp,%esi
call   1040 <gfx_outb@plt>
mov    $0x23,%edi
call   1030 <gfx_inb@plt>
mov    %eax,%ebp
mov    $0x22,%edi
mov    $0xc3,%esi
call   1040 <gfx_outb@plt>
movzbl %bl,%esi
mov    $0x23,%edi
call   1040 <gfx_outb@plt>
mov    %ebp,%eax
add    $0x8,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
define zeroext i8 @gfx_gxm_config_read(i8 zeroext %0) {
%2 = alloca i8
%3 = alloca i8
%4 = alloca i8
store i8 %0, i8* %2
store i8 -1, i8* %3
%5 = call i32 @gfx_outb(i32 34, i8 zeroext -61)
%6 = call zeroext i8 @gfx_inb(i32 35)
store i8 %6, i8* %4
%7 = call i32 @gfx_outb(i32 34, i8 zeroext -61)
%8 = load i8, i8* %4
%9 = zext i8 %8 to i32
%10 = or i32 %9, 16
%11 = trunc i32 %10 to i8
%12 = call i32 @gfx_outb(i32 35, i8 zeroext %11)
%13 = load i8, i8* %2
%14 = call i32 @gfx_outb(i32 34, i8 zeroext %13)
%15 = call zeroext i8 @gfx_inb(i32 35)
store i8 %15, i8* %3
%16 = call i32 @gfx_outb(i32 34, i8 zeroext -61)
%17 = load i8, i8* %4
%18 = call i32 @gfx_outb(i32 35, i8 zeroext %17)
%19 = load i8, i8* %3
ret i8 %19
}

LLVM IR (-O2):
define zeroext i8 @gfx_gxm_config_read(i8 zeroext %0) {
%2 = tail call i32 @gfx_outb(i32 34, i8 zeroext -61)
%3 = tail call zeroext i8 @gfx_inb(i32 35)
%4 = tail call i32 @gfx_outb(i32 34, i8 zeroext -61)
%5 = or i8 %3, 16
%6 = tail call i32 @gfx_outb(i32 35, i8 zeroext %5)
%7 = tail call i32 @gfx_outb(i32 34, i8 zeroext %0)
%8 = tail call zeroext i8 @gfx_inb(i32 35)
%9 = tail call i32 @gfx_outb(i32 34, i8 zeroext -61)
%10 = tail call i32 @gfx_outb(i32 35, i8 zeroext %3)
ret i8 %8
}