#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 */
int /*<<< orphan*/ outb(int, scalar_t__);
void write_reg_byte(short port, unsigned char reg, unsigned char value) {
  unsigned char outval;
  outb(0xE0 | reg, port + 0);
  outval = 0x40 | reg;
  outb(outval, port + 0);
  outb(outval, port + 0);
  outb((outval & 0xf0) | (value & 0x0f), port + 0);
  outb(value & 0x0f, port + 0);
  value >>= 4;
  outb(value, port + 0);
  outb(0x10 | value, port + 0);
  outb(0x10 | value, port + 0);
  outb(0xE0 | value, port + 0);
}


x86 assembly (clang, -O0):
<write_reg_byte>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %dl,%al
mov    %sil,%cl
mov    %di,%dx
mov    %dx,-0x2(%rbp)
mov    %cl,-0x3(%rbp)
mov    %al,-0x4(%rbp)
movzbl -0x3(%rbp),%edi
or     $0xe0,%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x3(%rbp),%eax
or     $0x40,%eax
mov    %al,-0x5(%rbp)
movzbl -0x5(%rbp),%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x5(%rbp),%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x5(%rbp),%edi
and    $0xf0,%edi
movzbl -0x4(%rbp),%eax
and    $0xf,%eax
or     %eax,%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x4(%rbp),%edi
and    $0xf,%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x4(%rbp),%eax
sar    $0x4,%eax
mov    %al,-0x4(%rbp)
movzbl -0x4(%rbp),%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x4(%rbp),%edi
or     $0x10,%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x4(%rbp),%edi
or     $0x10,%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x4(%rbp),%edi
or     $0xe0,%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<write_reg_byte>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %edx,%r14d
mov    %esi,%ebp
mov    %ebp,%eax
or     $0xe0,%al
movzbl %al,%eax
movslq %edi,%r15
mov    %eax,%edi
mov    %r15,%rsi
call   1030 <outb@plt>
or     $0x40,%bpl
movzbl %bpl,%ebp
mov    %ebp,%edi
mov    %r15,%rsi
call   1030 <outb@plt>
mov    %ebp,%edi
mov    %r15,%rsi
call   1030 <outb@plt>
and    $0xfffffff0,%ebp
mov    %r14d,%ebx
and    $0xf,%ebx
or     %ebx,%ebp
mov    %ebp,%edi
mov    %r15,%rsi
call   1030 <outb@plt>
mov    %ebx,%edi
mov    %r15,%rsi
call   1030 <outb@plt>
shr    $0x4,%r14b
movzbl %r14b,%ebx
mov    %ebx,%edi
mov    %r15,%rsi
call   1030 <outb@plt>
lea    0x10(%rbx),%ebp
mov    %ebp,%edi
mov    %r15,%rsi
call   1030 <outb@plt>
mov    %ebp,%edi
mov    %r15,%rsi
call   1030 <outb@plt>
or     $0xe0,%ebx
mov    %ebx,%edi
mov    %r15,%rsi
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
jmp    1030 <outb@plt>

LLVM IR (-O0):
define void @write_reg_byte(i16 signext %0, i8 zeroext %1, i8 zeroext %2) {
%4 = alloca i16
%5 = alloca i8
%6 = alloca i8
%7 = alloca i8
store i16 %0, i16* %4
store i8 %1, i8* %5
store i8 %2, i8* %6
%8 = load i8, i8* %5
%9 = zext i8 %8 to i32
%10 = or i32 224, %9
%11 = load i16, i16* %4
%12 = sext i16 %11 to i32
%13 = add nsw i32 %12, 0
%14 = sext i32 %13 to i64
%15 = call i32 @outb(i32 %10, i64 %14)
%16 = load i8, i8* %5
%17 = zext i8 %16 to i32
%18 = or i32 64, %17
%19 = trunc i32 %18 to i8
store i8 %19, i8* %7
%20 = load i8, i8* %7
%21 = zext i8 %20 to i32
%22 = load i16, i16* %4
%23 = sext i16 %22 to i32
%24 = add nsw i32 %23, 0
%25 = sext i32 %24 to i64
%26 = call i32 @outb(i32 %21, i64 %25)
%27 = load i8, i8* %7
%28 = zext i8 %27 to i32
%29 = load i16, i16* %4
%30 = sext i16 %29 to i32
%31 = add nsw i32 %30, 0
%32 = sext i32 %31 to i64
%33 = call i32 @outb(i32 %28, i64 %32)
%34 = load i8, i8* %7
%35 = zext i8 %34 to i32
%36 = and i32 %35, 240
%37 = load i8, i8* %6
%38 = zext i8 %37 to i32
%39 = and i32 %38, 15
%40 = or i32 %36, %39
%41 = load i16, i16* %4
%42 = sext i16 %41 to i32
%43 = add nsw i32 %42, 0
%44 = sext i32 %43 to i64
%45 = call i32 @outb(i32 %40, i64 %44)
%46 = load i8, i8* %6
%47 = zext i8 %46 to i32
%48 = and i32 %47, 15
%49 = load i16, i16* %4
%50 = sext i16 %49 to i32
%51 = add nsw i32 %50, 0
%52 = sext i32 %51 to i64
%53 = call i32 @outb(i32 %48, i64 %52)
%54 = load i8, i8* %6
%55 = zext i8 %54 to i32
%56 = ashr i32 %55, 4
%57 = trunc i32 %56 to i8
store i8 %57, i8* %6
%58 = load i8, i8* %6
%59 = zext i8 %58 to i32
%60 = load i16, i16* %4
%61 = sext i16 %60 to i32
%62 = add nsw i32 %61, 0
%63 = sext i32 %62 to i64
%64 = call i32 @outb(i32 %59, i64 %63)
%65 = load i8, i8* %6
%66 = zext i8 %65 to i32
%67 = or i32 16, %66
%68 = load i16, i16* %4
%69 = sext i16 %68 to i32
%70 = add nsw i32 %69, 0
%71 = sext i32 %70 to i64
%72 = call i32 @outb(i32 %67, i64 %71)
%73 = load i8, i8* %6
%74 = zext i8 %73 to i32
%75 = or i32 16, %74
%76 = load i16, i16* %4
%77 = sext i16 %76 to i32
%78 = add nsw i32 %77, 0
%79 = sext i32 %78 to i64
%80 = call i32 @outb(i32 %75, i64 %79)
%81 = load i8, i8* %6
%82 = zext i8 %81 to i32
%83 = or i32 224, %82
%84 = load i16, i16* %4
%85 = sext i16 %84 to i32
%86 = add nsw i32 %85, 0
%87 = sext i32 %86 to i64
%88 = call i32 @outb(i32 %83, i64 %87)
ret void
}

LLVM IR (-O2):
define void @write_reg_byte(i16 signext %0, i8 zeroext %1, i8 zeroext %2) {
%4 = or i8 %1, -32
%5 = zext i8 %4 to i32
%6 = sext i16 %0 to i64
%7 = tail call i32 @outb(i32 %5, i64 %6)
%8 = or i8 %1, 64
%9 = zext i8 %8 to i32
%10 = tail call i32 @outb(i32 %9, i64 %6)
%11 = tail call i32 @outb(i32 %9, i64 %6)
%12 = and i32 %9, 240
%13 = and i8 %2, 15
%14 = zext i8 %13 to i32
%15 = or i32 %12, %14
%16 = tail call i32 @outb(i32 %15, i64 %6)
%17 = tail call i32 @outb(i32 %14, i64 %6)
%18 = lshr i8 %2, 4
%19 = zext i8 %18 to i32
%20 = tail call i32 @outb(i32 %19, i64 %6)
%21 = or i32 %19, 16
%22 = tail call i32 @outb(i32 %21, i64 %6)
%23 = tail call i32 @outb(i32 %21, i64 %6)
%24 = or i32 %19, 224
%25 = tail call i32 @outb(i32 %24, i64 %6)
ret void
}